text:
const int kNumberLoadTestParts = 10;

#if defined(OS_MACOSX)
const int kDefaultKeyModifier = blink::WebInputEvent::MetaKey;
#else
const int kDefaultKeyModifier = blink::WebInputEvent::ControlKey;
#endif

// Using ASSERT_TRUE deliberately instead of ASSERT_EQ or ASSERT_STREQ
// in order to print a more readable message if the strings differ.
#define ASSERT_MULTILINE_STREQ(expected, actual) \
    ASSERT_TRUE(expected == actual) \
        << "Expected:\n" << expected \
        << "\n\nActual:\n" << actual

bool GetGuestCallback(content::WebContents** guest_out,
                      content::WebContents* guest) {
  EXPECT_FALSE(*guest_out);
  *guest_out = guest;
  // Return false so that we iterate through all the guests and verify there is
  // only one.
  return false;
}

class PDFExtensionTest : public ExtensionApiTest,
                         public testing::WithParamInterface<int> {
 public:
  ~PDFExtensionTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    content::IsolateAllSitesForTesting(command_line);
  }

  void SetUpOnMainThread() override {
    ExtensionApiTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
    content::SetupCrossSiteRedirector(embedded_test_server());
  }

  void TearDownOnMainThread() override {
    ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
    ExtensionApiTest::TearDownOnMainThread();
  }

  bool PdfIsExpectedToFailLoad(const std::string& pdf_file) {
    const char* const kFailingPdfs[] = {
        // TODO(thestig): Investigate why this file doesn't fail when served by
        // EmbeddedTestServer or another webserver.
        // "pdf_private/cfuzz5.pdf",
        "pdf_private/cfuzz6.pdf", "pdf_private/crash-11-14-44.pdf",
        "pdf_private/js.pdf",     "pdf_private/segv-ecx.pdf",
        "pdf_private/tests.pdf",
    };
    for (size_t i = 0; i < arraysize(kFailingPdfs); ++i) {
      if (kFailingPdfs[i] == pdf_file)
        return true;
    }
    return false;
  }

  // Runs the extensions test at chrome/test/data/pdf/<filename> on the PDF file
  // at chrome/test/data/pdf/<pdf_filename>.
  void RunTestsInFile(const std::string& filename,
                      const std::string& pdf_filename) {
    extensions::ResultCatcher catcher;

    GURL url(embedded_test_server()->GetURL("/pdf/" + pdf_filename));

    // It should be good enough to just navigate to the URL. But loading up the
    // BrowserPluginGuest seems to happen asynchronously as there was flakiness
    // being seen due to the BrowserPluginGuest not being available yet (see
    // crbug.com/498077). So instead use |LoadPdf| which ensures that the PDF is
    // loaded before continuing.
    content::WebContents* guest_contents = LoadPdfGetGuestContents(url);
    ASSERT_TRUE(guest_contents);

    base::FilePath test_data_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
    test_data_dir = test_data_dir.Append(FILE_PATH_LITERAL("pdf"));
    base::FilePath test_util_path = test_data_dir.AppendASCII("test_util.js");
    std::string test_util_js;
    ASSERT_TRUE(base::ReadFileToString(test_util_path, &test_util_js));

    base::FilePath test_file_path = test_data_dir.AppendASCII(filename);
    std::string test_js;
    ASSERT_TRUE(base::ReadFileToString(test_file_path, &test_js));

    test_util_js.append(test_js);
    ASSERT_TRUE(content::ExecuteScript(guest_contents, test_util_js));

    if (!catcher.GetNextResult())
      FAIL() << catcher.message();
  }

  // Load the PDF at the given URL and use the PDFScriptingAPI to ensure it has
  // finished loading. Return true if it loads successfully or false if it
  // fails. If it doesn't finish loading the test will hang. This is done from
  // outside of the BrowserPlugin guest to ensure the PDFScriptingAPI works
  // correctly from there.
  bool LoadPdf(const GURL& url) {
    ui_test_utils::NavigateToURL(browser(), url);
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    return pdf_extension_test_util::EnsurePDFHasLoaded(web_contents);
  }

  // Same as |LoadPdf|, but also returns a pointer to the guest WebContents for
  // the loaded PDF. Returns nullptr if the load fails.
  content::WebContents* LoadPdfGetGuestContents(const GURL& url) {
    if (!LoadPdf(url))
      return nullptr;

    content::WebContents* contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    content::BrowserPluginGuestManager* guest_manager =
        contents->GetBrowserContext()->GetGuestManager();
    content::WebContents* guest_contents =
        guest_manager->GetFullPageGuest(contents);
    return guest_contents;
  }

  // Load all the PDFs contained in chrome/test/data/<dir_name>. This only runs
  // the test if base::Hash(filename) mod kNumberLoadTestParts == k in order
  // to shard the files evenly across values of k in [0, kNumberLoadTestParts).
  void LoadAllPdfsTest(const std::string& dir_name, int k) {
    base::FilePath test_data_dir;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
    base::FileEnumerator file_enumerator(test_data_dir.AppendASCII(dir_name),
                                         false, base::FileEnumerator::FILES,
                                         FILE_PATH_LITERAL("*.pdf"));

    size_t count = 0;
    for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty();
         file_path = file_enumerator.Next()) {
      std::string filename = file_path.BaseName().MaybeAsASCII();
      ASSERT_FALSE(filename.empty());

      std::string pdf_file = dir_name + "/" + filename;
      if (static_cast<int>(base::Hash(filename) % kNumberLoadTestParts) == k) {
        LOG(INFO) << "Loading: " << pdf_file;
        bool success = LoadPdf(embedded_test_server()->GetURL("/" + pdf_file));
        EXPECT_EQ(!PdfIsExpectedToFailLoad(pdf_file), success);
      }
      ++count;
    }
    // Assume that there is at least 1 pdf in the directory to guard against
    // someone deleting the directory and silently making the test pass.
    ASSERT_GE(count, 1u);
  }

  void TestGetSelectedTextReply(GURL url, bool expect_success) {
    ui_test_utils::NavigateToURL(browser(), url);
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(pdf_extension_test_util::EnsurePDFHasLoaded(web_contents));

    // Reach into the guest and hook into it such that it posts back a 'flush'
    // message after every getSelectedTextReply message sent.
    content::BrowserPluginGuestManager* guest_manager =
        web_contents->GetBrowserContext()->GetGuestManager();
    content::WebContents* guest_contents = nullptr;
    ASSERT_NO_FATAL_FAILURE(guest_manager->ForEachGuest(
        web_contents, base::Bind(&GetGuestCallback, &guest_contents)));
    ASSERT_TRUE(guest_contents);
    ASSERT_TRUE(content::ExecuteScript(
        guest_contents,
        "var oldSendScriptingMessage = "
        "    PDFViewer.prototype.sendScriptingMessage_;"
        "PDFViewer.prototype.sendScriptingMessage_ = function(message) {"
        "  oldSendScriptingMessage.bind(this)(message);"
        "  if (message.type == 'getSelectedTextReply')"
        "    this.parentWindow_.postMessage('flush', '*');"
        "}"));

    // Add an event listener for flush messages and request the selected text.
    // If we get a flush message without receiving getSelectedText we know that
    // the message didn't come through.
    bool success = false;
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
        web_contents,
        "window.addEventListener('message', function(event) {"
        "  if (event.data == 'flush')"
        "    window.domAutomationController.send(false);"
        "  if (event.data.type == 'getSelectedTextReply')"
        "    window.domAutomationController.send(true);"
        "});"
        "document.getElementsByTagName('embed')[0].postMessage("
        "    {type: 'getSelectedText'});",
        &success));
    ASSERT_EQ(expect_success, success);
  }

  void ConvertPageCoordToScreenCoord(content::WebContents* contents,
                                     gfx::Point* point) {
    ASSERT_TRUE(contents);
    ASSERT_TRUE(content::ExecuteScript(contents,
        "var visiblePage = viewer.viewport.getMostVisiblePage();"
        "var visiblePageDimensions ="
        "    viewer.viewport.getPageScreenRect(visiblePage);"
        "var viewportPosition = viewer.viewport.position;"
        "var screenOffsetX = visiblePageDimensions.x - viewportPosition.x;"
        "var screenOffsetY = visiblePageDimensions.y - viewportPosition.y;"
        "var linkScreenPositionX ="
        "    Math.floor(" + base::IntToString(point->x()) + " + screenOffsetX);"
        "var linkScreenPositionY ="
        "    Math.floor(" + base::IntToString(point->y()) + " +"
        "    screenOffsetY);"));

    int x;
    ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
        contents,
        "window.domAutomationController.send(linkScreenPositionX);",
        &x));

    int y;
    ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
        contents,
        "window.domAutomationController.send(linkScreenPositionY);",
        &y));

    point->SetPoint(x, y);
  }

};

IN_PROC_BROWSER_TEST_P(PDFExtensionTest, Load) {
#if defined(GOOGLE_CHROME_BUILD)
  // Load private PDFs.
  LoadAllPdfsTest("pdf_private", GetParam());
#endif
  // Load public PDFs.
  LoadAllPdfsTest("pdf", GetParam());
}

class DisablePluginHelper : public content::DownloadManager::Observer,
                            public content::NotificationObserver {
 public:
  DisablePluginHelper() {}

  virtual ~DisablePluginHelper() {}

  void DisablePlugin(Profile* profile) {
    registrar_.Add(this, chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
                   content::Source<Profile>(profile));
    scoped_refptr<PluginPrefs> prefs(PluginPrefs::GetForProfile(profile));
    DCHECK(prefs.get());
    prefs->EnablePluginGroup(
        false, base::UTF8ToUTF16(ChromeContentClient::kPDFPluginName));
    // Wait until the plugin has been disabled.
    disable_run_loop_.Run();
  }

  const GURL& GetLastUrl() {
    // Wait until the download has been created.
    download_run_loop_.Run();
    return last_url_;
  }

  // content::DownloadManager::Observer implementation.
  void OnDownloadCreated(content::DownloadManager* manager,
                         content::DownloadItem* item) override {
    last_url_ = item->GetURL();
    download_run_loop_.Quit();
  }

  // content::NotificationObserver implementation.
  void Observe(int type,
               const content::NotificationSource& source,
               const content::NotificationDetails& details) override {
    DCHECK_EQ(chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, type);
    disable_run_loop_.Quit();
  }

 private:
  content::NotificationRegistrar registrar_;
  base::RunLoop disable_run_loop_;
  base::RunLoop download_run_loop_;
  GURL last_url_;
};

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, DisablePlugin) {
  // Disable the PDF plugin.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::BrowserContext* browser_context = web_contents->GetBrowserContext();
  Profile* profile = Profile::FromBrowserContext(browser_context);
  DisablePluginHelper helper;
  helper.DisablePlugin(profile);

  // Register a download observer.
  content::DownloadManager* download_manager =
      content::BrowserContext::GetDownloadManager(browser_context);
  download_manager->AddObserver(&helper);

  // Navigate to a PDF and test that it is downloaded.
  GURL url(embedded_test_server()->GetURL("/pdf/test.pdf"));
  ui_test_utils::NavigateToURL(browser(), url);
  ASSERT_EQ(url, helper.GetLastUrl());

  // Cancel the download to shutdown cleanly.
  download_manager->RemoveObserver(&helper);
  std::vector<content::DownloadItem*> downloads;
  download_manager->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());
  downloads[0]->Cancel(false);
}

// We break PDFTest.Load up into kNumberLoadTestParts.
INSTANTIATE_TEST_CASE_P(PDFTestFiles,
                        PDFExtensionTest,
                        testing::Range(0, kNumberLoadTestParts));

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Basic) {
  RunTestsInFile("basic_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, BasicPlugin) {
  RunTestsInFile("basic_plugin_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Viewport) {
  RunTestsInFile("viewport_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Bookmark) {
  RunTestsInFile("bookmarks_test.js", "test-bookmarks.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Navigator) {
  RunTestsInFile("navigator_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, ParamsParser) {
  RunTestsInFile("params_parser_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, ZoomManager) {
  RunTestsInFile("zoom_manager_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Elements) {
  // Although this test file does not require a PDF to be loaded, loading the
  // elements without loading a PDF is difficult.
  RunTestsInFile("material_elements_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, ToolbarManager) {
  RunTestsInFile("toolbar_manager_test.js", "test.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Title) {
  RunTestsInFile("title_test.js", "test-title.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, WhitespaceTitle) {
  RunTestsInFile("whitespace_title_test.js", "test-whitespace-title.pdf");
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PageChange) {
  RunTestsInFile("page_change_test.js", "test-bookmarks.pdf");
}

// Ensure that the internal PDF plugin application/x-google-chrome-pdf won't be
// loaded if it's not loaded in the chrome extension page.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureInternalPluginDisabled) {
  std::string url = embedded_test_server()->GetURL("/pdf/test.pdf").spec();
  std::string data_url =
      "data:text/html,"
      ""
      "<embed type=\"application/x-google-chrome-pdf\" src=\"" +
      url +
      "\">"
      "";
  ui_test_utils::NavigateToURL(browser(), GURL(data_url));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  bool plugin_loaded = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
      web_contents,
      "var plugin_loaded = "
      "    document.getElementsByTagName('embed')[0].postMessage !== undefined;"
      "window.domAutomationController.send(plugin_loaded);",
      &plugin_loaded));
  ASSERT_FALSE(plugin_loaded);
}

// Ensure cross-origin replies won't work for getSelectedText.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureCrossOriginRepliesBlocked) {
  std::string url = embedded_test_server()->GetURL("/pdf/test.pdf").spec();
  std::string data_url =
      "data:text/html,"
      ""
      "<embed type=\"application/pdf\" src=\"" +
      url +
      "\">"
      "";
  TestGetSelectedTextReply(GURL(data_url), false);
}

// Ensure same-origin replies do work for getSelectedText.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsureSameOriginRepliesAllowed) {
  TestGetSelectedTextReply(embedded_test_server()->GetURL("/pdf/test.pdf"),
                           true);
}

// This test ensures that PDF can be loaded from local file
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsurePDFFromLocalFileLoads) {
  base::FilePath test_data_dir;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
  test_data_dir = test_data_dir.Append(FILE_PATH_LITERAL("pdf"));
  base::FilePath test_data_file = test_data_dir.AppendASCII("test.pdf");
  ASSERT_TRUE(PathExists(test_data_file));
  GURL test_pdf_url("file://" + test_data_file.MaybeAsASCII());
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);
}

// This test ensures that link permissions are enforced properly in PDFs.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkPermissions) {
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  // chrome://favicon links should be allowed for PDFs, while chrome://settings
  // links should not.
  GURL valid_link_url("chrome://favicon/https://www.google.ca/");
  GURL invalid_link_url("chrome://settings");

  GURL unfiltered_valid_link_url(valid_link_url);
  content::RenderProcessHost* rph = guest_contents->GetRenderProcessHost();
  rph->FilterURL(true, &valid_link_url);
  rph->FilterURL(true, &invalid_link_url);

  // Invalid link URLs should be changed to "about:blank" when filtered.
  EXPECT_EQ(unfiltered_valid_link_url, valid_link_url);
  EXPECT_EQ(GURL("about:blank"), invalid_link_url);
}

// This test ensures that titles are set properly for PDFs without /Title.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabTitleWithNoTitle) {
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);
  EXPECT_EQ(base::ASCIIToUTF16("test.pdf"), guest_contents->GetTitle());
  EXPECT_EQ(base::ASCIIToUTF16("test.pdf"),
            browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
}

// This test ensures that titles are set properly for PDFs with /Title.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabTitleWithTitle) {
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-title.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);
  EXPECT_EQ(base::ASCIIToUTF16("PDF title test"), guest_contents->GetTitle());
  EXPECT_EQ(base::ASCIIToUTF16("PDF title test"),
            browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
}

// This test ensures that titles are set properly for embedded PDFs with /Title.
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabTitleWithEmbeddedPdf) {
  std::string url =
      embedded_test_server()->GetURL("/pdf/test-title.pdf").spec();
  std::string data_url =
      "data:text/html,"
      "<title>TabTitleWithEmbeddedPdf</title>"
      "<embed type=\"application/pdf\" src=\"" +
      url +
      "\">";
  ui_test_utils::NavigateToURL(browser(), GURL(data_url));
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(pdf_extension_test_util::EnsurePDFHasLoaded(web_contents));
  EXPECT_EQ(base::ASCIIToUTF16("TabTitleWithEmbeddedPdf"),
            web_contents->GetTitle());
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfZoomWithoutBubble) {
  using namespace zoom;

  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // The PDF viewer always starts at default zoom, which for tests is 100% or
  // zoom level 0.0. Here we look at the presets to find the next zoom level
  // above 0. Ideally we should look at the zoom levels from the PDF viewer
  // javascript, but we assume they'll always match the browser presets, which
  // are easier to access.
  std::vector<double> preset_zoom_levels = PageZoom::PresetZoomLevels(0.0);
  std::vector<double>::iterator it =
      std::find(preset_zoom_levels.begin(), preset_zoom_levels.end(), 0.0);
  ASSERT_TRUE(it != preset_zoom_levels.end());
  it++;
  ASSERT_TRUE(it != preset_zoom_levels.end());
  double new_zoom_level = *it;

  auto zoom_controller = ZoomController::FromWebContents(web_contents);
  // We expect a ZoomChangedEvent with can_show_bubble == false if the PDF
  // extension behaviour is properly picked up. The test times out otherwise.
  ZoomChangedWatcher watcher(zoom_controller,
                             ZoomController::ZoomChangedEventData(
                                 web_contents, 0.f, new_zoom_level,
                                 ZoomController::ZOOM_MODE_MANUAL, false));

  // Zoom PDF via script.
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
  EXPECT_EQ(nullptr, ZoomBubbleView::GetZoomBubble());
#endif
  ASSERT_TRUE(
      content::ExecuteScript(guest_contents, "viewer.viewport.zoomIn();"));

  watcher.Wait();
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
  EXPECT_EQ(nullptr, ZoomBubbleView::GetZoomBubble());
#endif
}

static std::string DumpPdfAccessibilityTree(const ui::AXTreeUpdate& ax_tree) {
  // Create a string representation of the tree starting with the embedded
  // object.
  std::string ax_tree_dump;
  base::hash_map<int32_t, int> id_to_indentation;
  bool found_embedded_object = false;
  for (auto& node : ax_tree.nodes) {
    if (node.role == ui::AX_ROLE_EMBEDDED_OBJECT)
      found_embedded_object = true;
    if (!found_embedded_object)
      continue;

    int indent = id_to_indentation[node.id];
    ax_tree_dump += std::string(2 * indent, ' ');
    ax_tree_dump += ui::ToString(node.role);

    std::string name = node.GetStringAttribute(ui::AX_ATTR_NAME);
    base::ReplaceChars(name, "\r", "\\r", &name);
    base::ReplaceChars(name, "\n", "\\n", &name);
    if (!name.empty())
      ax_tree_dump += " '" + name + "'";
    ax_tree_dump += "\n";
    for (size_t j = 0; j < node.child_ids.size(); ++j)
      id_to_indentation[node.child_ids[j]] = indent + 1;
  }

  return ax_tree_dump;
}

static const char kExpectedPDFAXTree[] =
    "embeddedObject\n"
    "  group\n"
    "    region 'Page 1'\n"
    "      paragraph\n"
    "        staticText '1 First Section\\r\\n'\n"
    "          inlineTextBox '1 '\n"
    "          inlineTextBox 'First Section\\r\\n'\n"
    "      paragraph\n"
    "        staticText 'This is the first section.\\r\\n1'\n"
    "          inlineTextBox 'This is the first section.\\r\\n'\n"
    "          inlineTextBox '1'\n"
    "    region 'Page 2'\n"
    "      paragraph\n"
    "        staticText '1.1 First Subsection\\r\\n'\n"
    "          inlineTextBox '1.1 '\n"
    "          inlineTextBox 'First Subsection\\r\\n'\n"
    "      paragraph\n"
    "        staticText 'This is the first subsection.\\r\\n2'\n"
    "          inlineTextBox 'This is the first subsection.\\r\\n'\n"
    "          inlineTextBox '2'\n"
    "    region 'Page 3'\n"
    "      paragraph\n"
    "        staticText '2 Second Section\\r\\n'\n"
    "          inlineTextBox '2 '\n"
    "          inlineTextBox 'Second Section\\r\\n'\n"
    "      paragraph\n"
    "        staticText '3'\n"
    "          inlineTextBox '3'\n";

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibility) {
  content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();

  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  WaitForAccessibilityTreeToContainNodeWithName(guest_contents,
                                                "1 First Section\r\n");
  ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
  std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
  ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityEnableLater) {
  // In this test, load the PDF file first, with accessibility off.
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-bookmarks.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  // Now enable accessibility globally, and assert that the PDF accessibility
  // tree loads.
  EnableAccessibilityForWebContents(guest_contents);
  WaitForAccessibilityTreeToContainNodeWithName(guest_contents,
                                                "1 First Section\r\n");
  ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
  std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
  ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
}

bool RetrieveGuestContents(
    content::WebContents** out_guest_contents,
    content::WebContents* in_guest_contents) {
  *out_guest_contents = in_guest_contents;
  return true;
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInIframe) {
  content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
  GURL test_iframe_url(embedded_test_server()->GetURL("/pdf/test-iframe.html"));
  ui_test_utils::NavigateToURL(browser(), test_iframe_url);
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  WaitForAccessibilityTreeToContainNodeWithName(contents,
                                                "1 First Section\r\n");

  content::WebContents* guest_contents = nullptr;
  content::BrowserPluginGuestManager* guest_manager =
        contents->GetBrowserContext()->GetGuestManager();
  guest_manager->ForEachGuest(contents,
                              base::Bind(&RetrieveGuestContents,
                                         &guest_contents));
  ASSERT_TRUE(guest_contents);

  ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
  std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
  ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, PdfAccessibilityInOOPIF) {
  content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
  GURL test_iframe_url(embedded_test_server()->GetURL(
      "/pdf/test-cross-site-iframe.html"));
  ui_test_utils::NavigateToURL(browser(), test_iframe_url);
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  WaitForAccessibilityTreeToContainNodeWithName(contents,
                                                "1 First Section\r\n");

  content::WebContents* guest_contents = nullptr;
  content::BrowserPluginGuestManager* guest_manager =
        contents->GetBrowserContext()->GetGuestManager();
  guest_manager->ForEachGuest(contents,
                              base::Bind(&RetrieveGuestContents,
                                         &guest_contents));
  ASSERT_TRUE(guest_contents);

  ui::AXTreeUpdate ax_tree = GetAccessibilityTreeSnapshot(guest_contents);
  std::string ax_tree_dump = DumpPdfAccessibilityTree(ax_tree);
  ASSERT_MULTILINE_STREQ(kExpectedPDFAXTree, ax_tree_dump);
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkCtrlLeftClick) {
  host_resolver()->AddRule("www.example.com", "127.0.0.1");
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-link.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  // The link position of the test-link.pdf in page coordinates is (110, 110).
  // Convert the link position from page coordinates to screen coordinates.
  gfx::Point link_position(110, 110);
  ConvertPageCoordToScreenCoord(guest_contents, &link_position);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  content::WindowedNotificationObserver observer(
      chrome::NOTIFICATION_TAB_ADDED,
      content::NotificationService::AllSources());
  content::SimulateMouseClickAt(web_contents, kDefaultKeyModifier,
      blink::WebMouseEvent::ButtonLeft, link_position);
  observer.Wait();

  int tab_count = browser()->tab_strip_model()->count();
  ASSERT_EQ(2, tab_count);

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_EQ(web_contents, active_web_contents);

  content::WebContents* new_web_contents =
      browser()->tab_strip_model()->GetWebContentsAt(1);
  ASSERT_TRUE(new_web_contents);
  ASSERT_NE(web_contents, new_web_contents);

  const GURL& url = new_web_contents->GetURL();
  ASSERT_EQ(std::string("http://www.example.com/"), url.spec());
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkMiddleClick) {
  host_resolver()->AddRule("www.example.com", "127.0.0.1");
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-link.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  // The link position of the test-link.pdf in page coordinates is (110, 110).
  // Convert the link position from page coordinates to screen coordinates.
  gfx::Point link_position(110, 110);
  ConvertPageCoordToScreenCoord(guest_contents, &link_position);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  content::WindowedNotificationObserver observer(
      chrome::NOTIFICATION_TAB_ADDED,
      content::NotificationService::AllSources());
  content::SimulateMouseClickAt(web_contents, 0,
      blink::WebMouseEvent::ButtonMiddle, link_position);
  observer.Wait();

  int tab_count = browser()->tab_strip_model()->count();
  ASSERT_EQ(2, tab_count);

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_EQ(web_contents, active_web_contents);

  content::WebContents* new_web_contents =
      browser()->tab_strip_model()->GetWebContentsAt(1);
  ASSERT_TRUE(new_web_contents);
  ASSERT_NE(web_contents, new_web_contents);

  const GURL& url = new_web_contents->GetURL();
  ASSERT_EQ(std::string("http://www.example.com/"), url.spec());
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkCtrlShiftLeftClick) {
  host_resolver()->AddRule("www.example.com", "127.0.0.1");
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-link.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  // The link position of the test-link.pdf in page coordinates is (110, 110).
  // Convert the link position from page coordinates to screen coordinates.
  gfx::Point link_position(110, 110);
  ConvertPageCoordToScreenCoord(guest_contents, &link_position);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  int modifiers = blink::WebInputEvent::ShiftKey | kDefaultKeyModifier;

  content::WindowedNotificationObserver observer(
      chrome::NOTIFICATION_TAB_ADDED,
      content::NotificationService::AllSources());
  content::SimulateMouseClickAt(web_contents, modifiers,
      blink::WebMouseEvent::ButtonLeft, link_position);
  observer.Wait();

  int tab_count = browser()->tab_strip_model()->count();
  ASSERT_EQ(2, tab_count);

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_NE(web_contents, active_web_contents);

  const GURL& url = active_web_contents->GetURL();
  ASSERT_EQ(std::string("http://www.example.com/"), url.spec());
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, LinkShiftMiddleClick) {
  host_resolver()->AddRule("www.example.com", "127.0.0.1");
  GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test-link.pdf"));
  content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
  ASSERT_TRUE(guest_contents);

  // The link position of the test-link.pdf in page coordinates is (110, 110).
  // Convert the link position from page coordinates to screen coordinates.
  gfx::Point link_position(110, 110);
  ConvertPageCoordToScreenCoord(guest_contents, &link_position);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  content::WindowedNotificationObserver observer(
      chrome::NOTIFICATION_TAB_ADDED,
      content::NotificationService::AllSources());
  content::SimulateMouseClickAt(web_contents, blink::WebInputEvent::ShiftKey,
      blink::WebMouseEvent::ButtonMiddle, link_position);
  observer.Wait();

  int tab_count = browser()->tab_strip_model()->count();
  ASSERT_EQ(2, tab_count);

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_NE(web_contents, active_web_contents);

  const GURL& url = active_web_contents->GetURL();
  ASSERT_EQ(std::string("http://www.example.com/"), url.spec());
}

redpajama_set_name: RedPajamaGithub


Choose from below List of 20 Couple Hotels Available in Matheran. Book online to get great deals and discounts on Matheran Couple Hotels in just one click.
Hotel service, staff, and rooms are awesome, but small wash room, swimming pool not properly managed. Breakfast and lunch was excellent, dinner was good, best thing is exact opposite to Matheran railway Station, but slightly costly.
Rangoli Retreat, just 1.4 km from Charlotte Lake, features a vegetarian restaurant, children's play area, disco room and pool.
Staff was good. But the hotel rooms were not up-to the mark. Food was good. We took AC room, but it was not up-to the mark in case of cleanliness and overall quality.
We stayed at Girivihar Hotel, Matheran. Hotel is very clean and maintained the standards. Rooms are very spacious and clean. One thing I loved the most is their food they served very delicious veg food. Staff was very polite and supportive. Only thing I was concern was that hotel is located very far from bajarpeth and it is advisable to return to your room before it is too dark in evening. Overall it was an amazing experience and I am fully satisfied with Girivihar hotel. Thanks all staff (specially the cook/Maharaj Ji and Pandurang).
Best for location and safety very happy with facilities WiFi, TV, purified drinking water, hot water 6 till 10 paid laundry food not provided but best restaurants are Around the hotel.
A perfect example of what they call 'aging with grace. This Hotel has been around for a good while now but still the rooms, swimming pool and overall premise are quite well kept. Another good thing about this place is its food. Both veg, non-veg at the restaurant as well as at the buffet is worth its price. The management also arranges gala events like karaoke, musical chair, Housie etc. They even have a small disc o' to shake a leg! Overall a nice Hotel with pleasant staff, right in the market area, all at an affordable price.
Outside there is 1 good veg hotel,radhey shyam hotel,food is good,quantity is also good.so the day stay in matheran is good.
Room space/size is very good, service staff is good, near Matheran Station. There is a fridge in my room is not working. Window is fitting properly. At least tea or coffee should provided in room package. Other wise OK.
We booked Adamo The village for a night stay and found hotel very comfortable for staying. Hotel property is present at a location nearby main market and well maintained though it is old one. The room where we stayed was neatly maintained and enough to accommodate 3 people. Freebies like soap, shampoo etc were present in the room and you can inquire for other things if needed to room service. One remarkable thing of hotel is food. We opted for dinner and breakfast and very satisfied with food they served. If lucky, you get to See magic show also. Overall it was really good stay for us and I recommend this hotel to others.
It was very nice stay. Nice and clean, live music, DJ, cool staff, swimming pool open for all, over all good ambiance. A bit far from market so must go for a package including food also, at least for breakfast and dinner. Lunch can be outside considering local sight seeing in day time only. Try Hakimi 's food for lunch! Food is nice and staff is friendly. Over all fully satisfied with our stay. Will come again.
Especially liked variety of activities offered. Grounds kept clean. Swings lovely. Staff friendly and quickly met any needs.
Limited hot water from 7 to 10 am and sometimes not very hot. Too many monkeys, need spaying program in Matheran. Can't sit outside room without some 6 to 10 ready to grab my water bottle. Swimming pool very nice, but again too many monkeys drinking from the pool when I am in the water. Unsure where to get out or when. Staff was great and food delicious. Overall loved our stay.
Good stay, I enjoyed with food and service.
Superb stay. Loved the place and staff, food was very good.
Good option for family as well as for couple. The new management of the Hotel is good, staff is helpful and cooperative. Also good food quality. Value for money.
Good option for family as well as for couple. The new management of the Hotel is good, staff is helpful and cooperative. Also good food quality.
The owner and his family stays besides the room of the cottage. The owner provided room services of tea and dinner within stipulated time. He guided us on locating various points. The rooms were small but clean and hygienic. The wash-room is an Indian toilet set up.
To begin with there is nothing here to call it even a hotel. Dogs and monkeys everywhere. In the rooms in the balcony in the lobby and even in the dining room. Dogs were even sitting outside my room at the night. There was no one to attend me as my room's TV remote was not there. The phone kept ringing but no one attended. I recommend no one to book this hotel. There are many other good options available. Also the person who sits on the reception is very rude the way he talks. I paid for online booking but instead of giving me a double room. He gave me a single room which was too small that one could not even breathe properly. The room was really not worth the price I paid for it. Really pathetic experience it was on our very first visit to Matheran.
The staff is co-operative. Location is in centre of Matheran, one Side is market and other Side is Lake and other points. Food provided is good. Property is very good as compared to other available options.
I made it up to Matheran with no reception at night and no where else to go. The owner denied me a place to stay as this place is couples and Indians only. In the fine print it does say it is couples only but not Indians only. The owner generously refunded my money promptly through MakeMyTrip, and called a friend to get me another room at only a slightly higher price. I thank the owner for his kindness in handling my unfortunate situation. I would request that the owner please make it obvious in the description and or title of the Hotel that it is a couples/indians only Hotel to avoid any further distressing situations.
Reasonable cost. Good stay with wholesome good veg buffet included. Rooms just has basic amenities. This could have been better. The resort has good space with swimming pool too. Also near to the market and Station. Service is OK and yes keep your valuables safe and rooms locked, as thief's would be lurking around. That's monkeys.


text:
De Milne-Edwards wezelmaki (Lepilemur edwardsi)  is een zoogdier uit de familie van de wezelmaki's (Lepilemuridae). De wetenschappelijke naam van de soort werd voor het eerst geldig gepubliceerd door Forbes in 1894.

Voorkomen
De soort komt voor in het oosten van Madagaskar.

Wezelmaki's
Endemisch dier uit Madagaskar
IUCN-status bedreigd

redpajama_set_name: RedPajamaWikipedia


Shown here is "El Amor Brujo" by Mitzi Linn.
Artist Note: A contemporary Day of the Dead scene in Oaxaca Mexico. Adam and Eve are waiting outside a nightclub called El Amor Brujo, wit ha couple of angels announcing their return from the Dead. Size: 7.5" x 9.5" Title Translates to - "Love the Enchanter"


CYPRESS, CA - The Cypress College women's water polo team (12-7, 2-3 OEC) made a statement in Wednesday's 13-1 victory at home over Saddleback College (6-8, 1-3 OEC). The 12-point margin of victory is the largest for Cypress water polo in conference play since the 2014 season.
Recent Charger of the Week recipient Kaylie Merrill recorded a season-high 16 saves to limit the Gauchos offense. Sophomore Ariel Burns led the Chargers with 6 goals and 3 steals, while Allison Gracia added 2 goals and 6 assists.
Women's water polo will return to action on Wednesday, October 18 at Orange Coast College. Game time scheduled for 3:00 pm.


text:
Kuraree
Education and Community Outreach
Town Hall Art Gallery
Share Your Memories
Other Exhibitions
WAFTA
Moorditj Bridyas
Heritage Perth
"… a place of innocent recreation and entertainment …"
In 1870, Perth people quickly took advantage of the new facilities and organised social events such as concerts and dances. Some early users of the hall raised money to help the City Council improve the facilities, while other activities supported all sorts of causes. The Town Hall was truly intended as a social centre.
Entertainments of all kinds – both amateur and professional – have been a feature of the Town Hall ever since. Concerts – popular as well as classical – continue to be popular. Plays and shows are still staged – the Town Hall has even been a venue for the Perth Festival Fringe. The Town Hall was also used as a cinema for a while in the early years of the twentieth century.
Sporting activities, such as boxing, fencing, callisthenics, and even badminton, also feature in the history of the Town Hall.
Celebrations over the years
Performances for all tastes
Dances at the Town Hall have always been popular and many community groups have organised balls there. Tuesday morning community shows still provide a popular program of entertainment for seniors.
Jane Jewell, daughter of the architect Richard Roach Jewell, sang a solo at the first concert held at the Perth Town Hall on 15 July 1870. 'The Elfin Echoes' is a setting of a poem by Tennyson. The composer is unknown. Performed by Valerie Bannan. MS supplied by RWAHS.
The Perth Congregational Choral Society were first off the mark. Their concert on 15 July 1870 was repeated by popular demand a few days later. All the musical forces of the colony were marshalled for a Grand Concert on 29 August 1870. This raised £43/15/8 (equivalent to more than $6000 today), given to the City Council for fitting out the building.
Local amateur musicians formed a group called the Minstrels of the West to raise money for a piano. They achieved their goal at their 10th concert in 1877.
Amateur music-making has always been important to the Perth community. Indeed, community singing at the Town Hall was a feature of the 1920s and 1930s, with radio broadcasts of these events to the West Australian community. Many local choral and instrumental groups have performed at the Town Hall over the years. The stage has also been popular with dancing schools for putting on end-of-year performances and for musical and theatrical competitions.
A concert performance on the Town Hall stage. The group is probably The Minstrels of the West. Royal Western Australian Historical Society. P1999.4423
Concert program for the tenth and final concert of the Minstrels of the West. State Library of Western Australia PR381/2
Audience at the Town Hall for the first community singing concert broadcast by 6WF, 1936. State Library of Western Australia 006489D.
Scouts dressed for performing plays and sketches at their annual meeting and display, 1934. State Library of Western Australia 095312PD.
Dining and dancing
The Town Hall today is an elegant and historic function venue.
As well as formal civic dinners and receptions, community organisations, private companies and ordinary people host monster tea parties, receptions and dinners in the Town Hall.
A tea and social in 1935 to celebrate the fiftieth anniversary of Mr Alfred Sandover's arrival in Western Australia. State Library of Western Australia 018921PD.
Town Hall dances have always been popular. Balls were a highlight of social activity in the early years of the Swan River Colony and the Town Hall provided the community with a new popular venue for dancing.
Dancing at the Postal Institute annual meeting and dance.
Image courtesy of the National Archives of Australia. NAA: K1131, W1552/D.
Patricia Langford, née Edmondson,
wearing her debutante gown,
on the Town Hall staircase,
at the Printers Ball, 1952.
Lance and Patricia Langford and friends at the Printers Ball, 1952.
Hand-made dress, jacket and
wrap worn by Elsie Weeks
for dances at the Town Hall,
1960s. Lent by Steve Weeks.
Many Perth couples met at Town Hall dances. Lance Langford remembers how a beautiful brunette named Patricia Edmondson caught his eye and he asked her for a dance. He was 19 and she was 16. There were many dance venues but the Town Hall was a favourite because it was the biggest, had a good floor for dancing and had a good band. Lance and Patricia married in 1954.
Exploring changing fashions of dress over 150 years of events at the Perth Town Hall
Steve Weeks also remembers the dances at the Town Hall in the early 1960s. As a child, his mother would bring him and he would sleep under the table! But later on, Steve danced there himself as a competitive ballroom dancer.
Steve Weeks remembers dances at the town hall
Social dance clubs have been popular at the Perth Town Hall for many years. This 1991 video shows the Amelia Club, which met on Wednesday nights. The pianist is Beryl Long. She continued to play for the dance clubs well into her 70s! Other clubs were Kui, Beehive and Harmony. The Kui Club started in 1947 and is still going at the Wembley Bowling Club. Most of the dance clubs moved out of the Town Hall to make way for the restoration in 2005.
The Coolbaroo Club
On 4 October 1954, the Coolbaroo Club held a Gala Royal Show Ball at the Perth Town Hall.
The Coolbaroo Club was an Aboriginal organisation well-known for its advocacy for Aboriginal rights and for organising social activities, especially dances. The City of Perth was a prohibited area for Aboriginal people, only abolished in 1954. Booking the Town Hall for their Gala Royal Show Ball celebrated the abolition of the prohibited area and publicly reclaimed the right to be on Aboriginal land. The Coolbaroo Club continued to hold events in the Town Hall for the rest of the decade.
Farley Garlett interviews Albert and Irene McNamara about their memories of the Coolbaroo Club
Find out more about the Coolbaroo Club from the City of Perth's new podcast 'Untold Stories of Perth'
Listen to Untold Stories of Perth
A wide range of sporting contests have been held in the Town Hall, including boxing, badminton, fencing, callisthenics.
The first State Badminton Championships were held at the Perth Town Hall in 1927 and in 1950 the Australian Championships finally came to WA for the first time. 1951 saw the State Fencing Championships at the Town Hall.
Boxing was controversial. Boxing was very popular, but there was also considerable opposition to the sport. Consequently, the use of the Town Hall for boxing matches was very controversial.
Lotteries were also controversial. There was strong opposition to the formation of the Lotteries Commission (now Lotterywest) in the 1930s. A 1933 meeting to protest against the refusal of the Lotteries Commission to allow newspaper competitions was said to be the biggest ever held at the Perth Town Hall. Nevertheless, the Lotteries Commission held public draws at the Perth Town Hall for many years.
First public lottery draw at the Perth Town Hall, 1932. SLWA 101652PD
Junior boxing match at the Perth Town Hall. WA Newspapers
A craze for 'rinking'
One of the more surprising uses for Perth Town Hall was for roller skating – or 'rinking' as it was known.
The craze for roller skating arrived in Australia in the 1860s and a rinking club was formed in Perth in 1877. This was strictly an upper-class affair and the members met twice a week in the Town Hall.
The club held a remarkable costume ball on 17 October 1878, recorded in detail in the local papers and by Henry Prinsep's sketch of the event. The most 'original and remarkable dress' was undoubtedly Captain Wilkinson's Cleopatra's Needle costume – which must have been very difficult to skate in!
The craze grew and within ten years commercial operators stepped in and established several skating rinks in Perth and Fremantle. Mr George Webb set up the Broadway Elite Skating Rink at the Perth Town Hall.
Roller skating was a popular family affair. Advertisements invited 'Girls and Boys, their Fathers, Mothers, Grandmothers and Grandfathers and the Baby FREE'. On Boxing Day 1888, 5000 people were expected to attend the Town Hall rink over morning, afternoon and evening sessions. As well as general skating, there were organised games and competitions for adults and children, fast skating and races. Exhibitions of trick skating entertained the crowds, with a band supplying music.
Our friend Migo having subsequently very narrowly escaped drowning while swimming to this island, I distinguished it by the name of "Isle Migo" in remembrance of him and his many sterling good qualities.
John Septimus Roe's diary
Miago (sometimes spelt Migo in documents) was a well-known figure in Perth in the 1830s. According to his granddaughter Fanny Balbuk Yooreel, Kuraree, the site of the Perth Town Hall, was one of Miago's favourite camp sites.
Miago's boodja was in the Upper Swan area, but he had family links across the whole of the Swan and Canning, as well as towards Pinjarra and the Murray River. He was related to many other well-known Nyoongar leaders of the time, such as Munday, Yagan and Midgegooroo.
Miago was well-known to the settlers, and friendly with some of their leaders. Local newspapers often describe him as a 'messenger of peace' and 'ambassador'. He had a great reputation as a tracker and guide.
Elder Farley Garlett tells the story of Miago
A respected leader
When the settlers arrived in 1829, Miago was quick to grasp what was happening and quick to position himself as an interpreter and mediator between his people and the settlers. Miago worked hard to make peace by building relationships with the settlers and finding ways for his people to maintain their culture.
In 1833, he went with Munday to meet Governor Stirling. They explained how the actions of the settlers were affecting the daily lives of Whadjuk Nyoongar people. In 1835, Miago organised a peace meeting between Governor Stirling, Swan River people and the people from the Murray River, after the Pinjarra massacre. This included persuading the Governor to host a jeena middar (corroboree). This was held in the Kuraree area, close to the site of the Perth Town Hall.
Miago was obviously well-respected by his people. At a gathering in 1849 he was chosen as a leader of the Whadjuk Nyoongar living in the Perth area.
Many of the settlers respected him too. This gave him a chance to try to explain the Nyoongar way of life. For example, he lived in George Grey's house for several months, teaching him about Nyoongar customs and language.
C.D. Wittenoom's sketch of Perth in 1839, as Miago would have known it.
A brave traveller and song man
Miago must have been brave. He travelled with explorers as guide and interpreter – even to strange places where he believed the people would be hostile.
Miago travelled with John Septimus Roe to the Albany area, where Roe named Migo Island after him. He also sailed on the Beagle's expedition to the Northwest. Stokes often mentions him in his diary of the voyage.
Stokes tells us in his diary that Miago often sang during the Beagle voyage to keep his courage up when he was homesick. None of Miago's songs were written down, but Grey wrote down other Nyoongar songs about his adventures at sea. Miago's mother sang about her worries about him going into danger on the ship – her song became well-known and was sung by other Whadjuk Nyoongar travellers.
Extract from Grey's handwritten notes on the Nyoongar songs associated with Miago. National Library of South Africa, Capetown
Reviving Nyoongar songs
George Grey wrote down the words for two songs associated with Miago.
Dr Clint Bracknell, songwriter and music researcher at Edith Cowan University, has composed music for these words. They are performed here by celebrated singer-songwriter Gina Williams and guitarist Guy Ghouse.
The first song is introduced with the spoken words Ngany norp, baal bokadja woora (my son, he away far).
Grey recorded the words of this song as: ship bal win-jal bat-tar-dal gool-an-een. He translated it as 'Whither is this lone ship moving away'. This song was said to have been sung by Miago's mother while he was away on the Beagle voyage.
The second song is introduced with the spoken words Baal kaarlak koorl, yeyi ngaala waangk (he home go, now we say).
Grey recorded the words as Kan-de maar-o, kan-de maar-a-lo, Tsail-o mar-ra, tsail-o mar-ra. His translation is: 'Unsteadily shifts the wind-o, unsteadily shifts the wind-o, The sails-o handle, the sails-o handle-ho'. This song was popular after Miago's return and seems to describe his experience aboard ship.
This project has been supported and endorsed by the City of Perth's Nyoongar Elders advisory committee.
KurareeThe BuildingCivic LifeCommunity
Cabinet of curiositiesWhere are they now?Education and
Community OutreachTown Hall Gallery
Heritage PerthWAFTA ExhibitionMoorditj Bridyas Exhibition
P 08 9461 3333 • E heritageperth@cityofperth.wa.gov.au
Website and Branding by Crush
closearrow-circle-o-downbars linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram

redpajama_set_name: RedPajamaCommonCrawl


Search employment opportunities in Singapore - Job ad posting site for work in Singapore for foreigners, Americans. Singapore jobs for expats, English speakers, westerners. Find teaching, HR, sales, marketing, nurse, medical, technician, engineer, IT jobs abroad in Europe, China, India, Qatar, Dubai, UAE for US, British citizens. Post jobs for free in UK, London, Germany, Holland, Canada. Free job postings USA - CA, NY, TX, FL. Post CV for working in Singapore, jobs for graduates, foreign nationals, internship job boards.


text:
Q: Why is ObjectInputStream readObject() throwing EOF exception I am stuck with this very strange problem. In the client I am passing in objects like
try{
    oos.writeObject(new GameStartSerializedObject());
    oos.flush();
}
catch(Exception e){
    e.printStackTrace();
}

and in the server I am reading the object
try{
    //Its my turn
    thrown_message = player_reader.readObject();
}
catch(Exception e){

My question is why am i getting EOF exception. My understanding of object input stream is when i call readObject() i should block until i get an object so how does it know if the eof is reached? Please help!
This is how I create object streams
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();

Also, after i write object and flush should i close the stream. I am not closing it since the objects are written pretty regularly from different parts of the code one after another.

A: The peer has closed the connection. Ergo there are no more objects to read. Ergo you have reached the end of the stream. Ergo readObject() throws EOFException.

redpajama_set_name: RedPajamaStackExchange


text:
Posted on August 25, 2017 by girlone
TINY MAGNETIC PETS – Deluxe/Debris
Warm electropop from the Pet Shop Toys…
Quite how electronic music entered a sudden renaissance period in the past 10 years is something that's ripe for commentary and discussion. Certainly, there's been an active contemporary electronic music scene in recent years that appears to show no signs of slowing down.
One of the bands to emerge during this fervent period has been the Dublin-based trio of Tiny Magnetic Pets. Consisting of Paula Gilmer, Seán Quinn and Eugene Somers, the outfit have established themselves through a series of EP releases and their 2009 debut album Return Of The Tiny Magnetic Pets.
The band cite the likes of Low-era Bowie, Brian Eno, Neu!, Boards Of Canada, Kraftwerk and OMD as influences. As inspiration goes, that's a solid and eclectic list to draw from and has now led the band to release their latest long-player in the form of Deluxe/Debris on the Happy Robots label (the outlet that also gave us Pattern Language).
Deluxe/Debris delivers a collection of serviceable electropop numbers through a definite desire to embrace a warm, analogue sound and Gilmer's whispery, wistful vocals. 'Lost My Guiding Light', like much of the material on the album, leans heavily in the pop direction. The combination of shimmering guitars and electronics slots in effortlessly atop a slick, smooth production.
The album also boasts collaborative efforts with former Kraftwerk member Wolfgang Flür, including the dynamic 'Radio On'. Here, thumping electronic rhythms and sweeping melodies allow Gilmer to really stretch her vocal talents. There's a robust, crunchy foundation to this composition that brings to mind the 'lost' electropop outfit Mirrors and is one of the album's finest moments.
Deluxe/Debris also serves up a series of intriguing (mostly) instrumental numbers that appear to serve as breakpoints. This is typified by the atmospheric warmth of 'Cloud Sequence'. Then there's the plaintive piano melodies and Mellotron moods of 'Cold War Neon'. Here, the composition presents a moment of reflection, complete with an oddly evocative French dialogue that drifts in and out of the piece.
The subtle, slow-burning appeal of 'Here Comes The Noise I (Pink)' segues into the more muscular 'Here Comes The Noise II (White)', which has a percussive warmth that suggests elements of OMD.
There's a particular warmth and robustness to album closer 'Never Alone' (the second of the Flür collaboration tracks) which rounds things off with style.
More recently, Tiny Magnetic Pets have been selected as support for OMD on the pioneering synthpop outfit's forthcoming Punishment Of Luxury tour. It's an element of approval that suggests the 3-piece are making the right noises, as well as presenting an opportunity for the band to reach a broader audience.
As an album, Deluxe/Debris presents several flavours that gives a very diverse ensemble. They've got the chops to push the envelope, but there are times on this album where, arguably, the band appear happier playing from a safe position. When they introduce their more experimental side, or opt for a more dynamic approach, Tiny Magnetic Pets shine brightest.
Nonetheless, this album showcases a band that's still unfurling their feathers and suggests that they're on a journey that's going to deliver some memorable electropop in the future.
Deluxe/Debris is out now on Happy Robots Records.
https://www.facebook.com/pg/tinymagneticpets
https://soundcloud.com/tinymagneticpets
https://tinymagneticpets.bandcamp.com/
Tiny Magnetic Pets are supporting OMD on the following dates:
23rd October: Vicar Street, Dublin, Ireland, 24th October: Mandela Hall, Belfast, 29th October: Empire Theatre Liverpool, 30th October: Colston Hall Bristol, 1st November: Cliffs Pavilion, Southend On Sea, 2nd November: Regent Theatre, Ipswich, 3rd November: Cambridge Corn Exchange, Cambridge, 5th November: De Montfort Hall, Leicester, 6th November: Royal Concert Hall, Nottingham, 7th November: Sheffield City Hall, Sheffield, 9th November: The Hexagon, Reading, 10th November: O2 Guildhall, Southampton, 11th November, G Live, Guildford, 13th November, Roundhouse London, 15th November: De La Warr Pavilion, Bexhill-On-Sea, 17th November: Manchester Academy, Manchester, 18th November: York Barbican, York, 19th November: Royal Concert Hall, Glasgow, 21st November: Symphony Hall, Birmingham, 22nd November, The Sage, Gateshead.
Ticket details via http://www.omd.uk.com/shows
CategoriesReviews TagsTiny Magnetic Pets
Previous PostPrevious ELECTRO PUNK PARTY
Next PostNext BLANCMANGE – The Blanc Tapes


text:
HB19-1091
Conservation Easement Transparency
Concerning conservation easement transparency.
A conservation easement is an agreement in which a property owner agrees to limit the use of his or her land in perpetuity in order to protect one or more specified conservation purposes. The instruments creating the conservation easement are recorded in the public records affecting the ownership of the property. The conservation easement is held by a third party, which monitors the use of the land and ensures that the terms of the agreement are upheld.
Prior to creating a conservation easement, the bill requires the property owner to sign a disclosure form acknowledging certain specified consequences and risks of creating the easement on his or her land.
The bill requires the commissioner of agriculture to work with local government officials to create a database of conservation easements in the state. The database includes specified information about the easements and a corresponding map displaying each easement in the state relative to county boundaries. Local government officials and the commissioner of agriculture are authorized to enter into contracts to assist in gathering information for the database. The bill specifies the sources of information that may be used to create the database. The commissioner of agriculture is required to annually update the information in the database and make the information and corresponding map available to the public at no charge on the department of agriculture's website.
When a conservation easement agreement, amendment, or transfer is recorded with a county clerk and recorder, the bill requires a complete copy of the agreement, amendment, or transfer to be submitted to the commissioner of agriculture and the county tax assessor of the county in which the easement is located. The commissioner of agriculture is required to create a tracking form with specified information for each conservation easement agreement, amendment, or transfer submitted. The tracking forms are made available on the department of agriculture's website and can be used by the commissioner of agriculture to create and maintain the database of conservation easements.
If a single property owner acquires both a conservation easement and title to the underlying property, current law allows the conservation easement to be released, terminated, extinguished, or abandoned by a process known as "merger". The bill prohibits a conservation easement from being extinguished by taking fee title to the land to which the conservation easement is attached.
For any state income tax credit claimed for a donation of a conservation easement that is disallowed, the bill allows a landowner to elect to either extinguish the conservation easement for which the credit was claimed or receive an equitable relief payment from the state. If a landowner elects to extinguish the conservation easement, the bill requires the department of revenue to reimburse the taxpayer for all reasonable costs incurred by the landowner in establishing the conservation easement donation as well any federal or state income tax liability incurred by the taxpayer. The attorney general is required to assist landowners with executing any documents required to seek a court order to extinguish a conservation easement.
(Note: This summary applies to this bill as introduced.)
View Recent Bill Text
View Recent Fiscal Note
Prime Sponsors
Kimmi Lewis
Rural Affairs & Agriculture
All Versions (1 )
01/14/2019 Introduced PDF
Fiscal Notes (1)
01/31/2019 FN1 PDF
Committee Actions
02/04/2019 | House Rural Affairs & Agriculture (3 )
Committee ReportHearing Summary
Adopt amendment L.002 [Attachment P].
The motion passed without objection.
Vote Summary
Refer House Bill 19-1091, as amended, to the Committee on Appropriations.
The motion failed on a vote of 4-7.
Postpone House Bill 19-1091 indefinitely using a reversal of the previous roll call. There was no objection to the use of the reverse roll call, therefore, the bill was postponed indefinitely.
The motion passed on a vote of 7-4.
Amendment Number
Committee/Floor Hearing
L.002
HOU Rural Affairs & Agriculture
Passed*
* Amendments passed in committee are not incorporated into the measure unless adopted by the full House or Senate.
** The status of Second Reading amendments may be subsequently affected by the adoption of an amendment to the Committee of the Whole Report. Refer to the House or Senate Journal for additional information.
02/04/2019 House House Committee on Rural Affairs & Agriculture Postpone Indefinitely
01/14/2019 House Introduced In House - Assigned to Rural Affairs & Agriculture
Rep. K. Lewis
Government Agency Special Event Permit Eligibility
Privatizing Public Safety Driving Test Retake
Colorado Secure Savings Plan
2017 Police Officers' and Firefighters' Pension Reform Commission Final Report
Local Government Sales and Use Taxes (17-26)
Construction Defect Laws and Issues (2015)


text:
A blockbuster retrospective of Leonardo da Vinci opens Thursday at the Louvre museum to mark 500 years since the death of the Renaissance master in the historic town of Amboise, France.
Nearly 200,000 people have already reserved their place in line for the exhibition, the biggest ever organised to showcase the Tuscan polymath's indelible contributions to humanity — with an emphasis on his painting.
A decade in the planning, the show simply titled "Leonardo da Vinci" groups 162 works, including 24 drawings loaned by Queen Elizabeth II of Britain from the Royal Collection.
The British Museum, the Hermitage of Saint Petersburg and the Vatican have also contributed, as well as, of course, Italy — after a sometimes acrimonious tug-of-war between Rome and Paris over the loans.
The exhibition in the Hall Napoleon features 11 of the 20 paintings definitively attributed to the Renaissance master, as well as drawings, manuscripts, sculptures and other objets d'art.
The show walks the visitor through the timeline of the master's peripatetic life under the tutelage of dukes, princes and kings, from Florence to Milan, Venice and Rome, and finally France, where he spent the last three years of his life.
Two notable no-shows — for different reasons
Two works are missing from the show, starting with the Mona Lisa.
Organisers decided the world's most famous painting should remain in the Louvre's Salle des Etats — its normal home — to help avoid overcrowding.
As it is, the masterpiece attracts nearly 30,000 people a day.
The Mona Lisa's ineffable smile will however beguile visitors in a virtual reality experience at the end of the Leonardo show, which runs until February 24.
The other notable no-show is the Salvator Mundi, the work that became the most expensive painting ever sold when it fetched $450 million (400 million euros) at a Christie's auction in 2017.
Mystery now surrounds the painting — whose authenticity is disputed by some experts — as it has not been seen in public ever since the stunning sale.
Officially, it was to be displayed at the Louvre Abu Dhabi but an unveiling set for September 2018 was inexplicably postponed. The Louvre said the museum's request to borrow the work is still pending.
Late runner: The Vitruvian Man
The final act in the row between Paris and Rome over Italy's contributions to the show came with a last-minute legal effort to halt the loan of the iconic Vitruvian Man drawing.
Last week an Italian court rejected a bid by an association advocating for the protection of Italy's heritage — Italia Nostra (Our Italy) — to halt the loan of the work dating from the late 15th century, arguing that it was too fragile to travel.
A spat over Italy's contributions to the Louvre show erupted late last year when the new populist rulers in Rome took issue with the previous government's agreement with Paris.
Lucia Borgonzoni, the number two in Italy's culture ministry and a member of the anti-immigration League party, argued that the accord was lopsided in favour of France.
At the height of the row, it appeared that Italy would cancel the accord altogether. It was finally resolved with Paris pledging to loan several Raphaels to Rome next year, the quincentenary of that artist's death.
The Vitruvian Man — which Italian media say is insured for at least one billion euros — will join the Louvre show later this month, but only for a few weeks rather than the full four months.
The drawing, kept in a climate-controlled vault in the Accademia Gallery in Venice, is rarely displayed to the public.
The exhibition curated by the Louvre's Vincent Delieuvin and Louis Frank, the heads of the museum's painting and graphic arts departments, includes infrared reflectographs that offer an insight into the master painter's techniques.
Tags: Leonardo Da Vinci, Louvre, Paris
Joan Stern
NYC fashion writer blogging about all things lux. Attending New York University, future Fashionista. Follow author Joan Stern on Google +.
Empire State Building Observatory Reopens
How to Open Champagne (And Why It Shouldn't Pop)
The Overhead Compartment with Kareem Abdul-Jabbar
The World's Best Cognac Bars
Sneak Peek At Karl Lagerfeld's Office In Paris
Imbibe Like The Great Writer Himself At 'Bar Hemingway'
Renowned Chefs Join Green Cuisine Crusade
Allee Sonia Rykiel: First Paris Street Named After A Fashion Designer
The World's Most Iconic Fountains
Champs-Elysees To Be Adored With Crystal And Bronze Fountains
Chanel Transforms The Grand Palais Into A Beach


As part of its ongoing commitment to providing affordable first class aftersales support for its widespread customer base, Industrial Floorcare Machines (UK) has announced that it has entered in to a strategic partnership with newly formed 1st Fix Machine Solutions, to provide complete aftersales service and breakdown repairs, supplementing its own in-house engineering resource.
1st Fix Machine Solutions was formed in January 2014 when Roy Cole, Director and Founder, recognised that the cleaning industry would benefit from an independent, reliable and high quality service provider. 1st Fix Machine Solutions is that service company, offering a fast response to customers.
Specialising in strategies to ensure a 1st time fix of machines, its mobile service engineers are trained and equipped to efficiently deliver the best levels of customer service. They will use technology to the full, ensuring effective communication at all stages of the service process. Tablets complete with modern, proven service software, full drawing access and satellite navigation will give them the ability to receive full breakdown details, as well as list exactly what they have done, what parts they have fitted, view manufacturers' drawings and capture a customer signature.
"The mutual aim of IFM (UK) and 1st Fix Machine Solutions is to exceed our customers' expectations and we will achieve this with a world class IT solution, excellent communication and the best engineers in the field," they say.
Image: Simon Collins, Managing Director of Industrial Floorcare Machines (UK), with some of the machines he sells.


Trying to figure out WordPress remote publishing… send me helpful links.
Is this thing working?… maybe.
WordPress plugin, http://www.gilfether.com/socialite/, test posting to twitter and facebook simultaneously. If you know of other tools, let me know!
I'm posting this "first" blog post on my online 'artshop'… testing something for work at IFSA-Butler, preparing for possible blog setup requests.


1 stores are offering it on Ebay with promotion codes. Other top features are Seat Cover, Car Seat Cover and Free. Also universal fit waterproof car seat is one of the top sellers in Baby Trend Car Seat Cover, Baby Girl Car Seat Covers, Seat Cover With Pockets and S in 2019.
Universal with Free Best Non-Slip Perfect Sports, Yoga your and Protect against everyday the Seat Cover.
While tend to and you sit them, the sharkskin-like.


Winona Ryder will soon share screen space with John Turturro, Anthony Boyle, Zoe Kazan, Morgan Spector, Caleb Malis, and Azhy Robertson in HBO's upcoming mini-series The Plot Against America. According to Variety, the show is an adaptation of Philip Roth's novel by David Simon and Ed Burns.
The series will imagine an alternate American history told through the eyes of a working-class Jewish family in New Jersey as they watch the political rise of Charles Lindbergh, an aviator hero and xenophobic populist, who defeats Franklin D Roosevelt, becomes president and turns the nation towards fascism. The Hollywood Reporter writes that the show's production began on 10 April.
Ryder will be seen as Evelyn Finkel, an unmarried woman, whose plans are pushed back by ten years as she has to look after her ill mother. Turturro plays Rabbi Lionel Bengelsdorf, a Lindbergh supporter, whose sudden attention is exhilarating for her. Kazan portrays Elizabeth "Bess" Levin, Evelyn's younger sister, described as an insightful mother and homemaker, who tries to protect her family from the volatile political climate. Spector is Bess's husband Herman, who tries to maintain normalcy in his life despite the unfavourable circumstances taking over his country. Boyle essays the role of Alvin, Herman's orphaned nephew while Robertson is Levin, the youngest child in the Levin family.
Newcomer Malis will portray Bess and Herman's son, Sandy, who rebels against his family's ideologies and becomes a Lindbergh supporter.


text:
<Customer CustomerID="DUMON">
	<CompanyName>Du monde entier</CompanyName>
	<ContactName>Janine Labrune</ContactName>
	<ContactTitle>Owner</ContactTitle>
	<Address>67, rue des Cinquante Otages</Address>
	<City>Nantes</City>
	<Region/>
	<PostalCode>44000</PostalCode>
	<Country>France</Country>
	<Phone>40.67.88.88</Phone>
	<Fax>40.67.89.89</Fax>
</Customer>


text:
Piercing Bump vs. Keloid: The Difference & How to Treat Each
Contributing writer By Kirsten Nunez, M.S.
Kirsten Nunez is a health and lifestyle journalist based in Beacon, New York. She has a Master of Science in Nutrition from Texas Woman's University and Bachelor of Science in Dietetics from SUNY Oneonta.
Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each
Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each
Image by Alba Vitta / Stocksy
Share on: Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each
Share on: Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each Piercing Bump vs. Keloid: The Difference & How to Treat Each
If you're a fan of jewelry, getting a new piercing can be oh-so-exciting. But what happens if you look in the mirror to admire your bling, only to find a mysterious lump? Well, it may be a piercing bump or keloid, which can be difficult to tell apart.
Regardless of the type of piercing, finding a bump can be a bit concerning. This is totally understandable, especially if you're a piercing newbie. To help you out, we've outlined the differences between piercing bumps vs. keloids, plus what to do for each, below.
Piercing bump
Piercing bump care
Keloid care
What is a piercing bump?
First things first: "Piercing bump" isn't a medical term. It's an informal description of what might develop after you get a piercing. That being said, there are multiple possible causes of a piercing bump.
Most commonly, a bump is a natural response to physical trauma. After all, a piercing literally injures the skin, which triggers the body's healing response. It's similar to what happens if you accidentally cut yourself with a kitchen tool, says board-certified dermatologist Loretta Ciraldo, M.D., FAAD. The bump is essentially a form of short-lived swelling, she explains, adding that it may feel tender and painful when pressed.
In some cases, a bump might mean that the piercing is infected, especially if the surrounding skin is very red or dark (depending on your skin tone). An infected bump might also release pus or blood and develop a yellow/honey-colored crust, notes Ciraldo.
What is a keloid?
"The less common but more troublesome type of bump is a keloid," says Ciraldo. This is a hard and rubbery permanent scar that's caused by abnormal wound healing. Unlike a typical scar, a keloid develops beyond the initial area of injury, so it will be larger than the actual wound—in this case, the hole of a piercing. What's more, keloids can continue to grow, so they can become quite large.
To put things into perspective, keloids have three times more collagen (e.g., the protein that gives structure to the skin) than hypertrophic scars, or thick raised scars. They also have 20 times more collagen than healthy skin tissue. The excess collagen accumulates at the piercing site, resulting in a skin growth. Other possible keloid symptoms include itching, burning, and pain.
You may be more likely to develop keloids if you have a darker skin tone. The same goes if you have a personal or family history of keloid formation, according to Ciraldo.
How to tell the difference between them.
If you're not sure whether you have a piercing bump or keloid, take note of three main factors: how long it lasts, where it is in the skin, and how far it spreads.
Timing: According to Ciraldo, a piercing bump is a temporary area of swelling. In other words, it won't hang around forever. Instead, it will get smaller each week, often disappearing (or becoming nearly unnoticeable) after six weeks, she explains. On the flip side, a keloid is a permanent bump. It might also continue to grow over weeks, months, or years, which can happen slowly or quickly, according to the American Academy of Dermatology Association.
Placing: The lesions also differ in relation to your skin's surface. A piercing bump is under the surface of your skin, says Ciraldo, so it will only become more evident when the area is touched. Meanwhile, a keloid grows on top of the skin's surface, so it will be easily visible and palpable, she notes.
Space: Finally, the "span" of a piercing bump vs. keloid is significantly different. Generally, a piercing bump is limited to the actual hole of the piercing; it might even look like a tiny flesh-colored ball underneath the earring. In contrast, a keloid will likely spread to beyond the piercing site, especially as it continues to grow.
How to care for a piercing bump.
If you have a piercing bump sans signs of infection, continue the usual steps for aftercare. This often means cleaning the piercing with saline and leaving it alone as much as possible. Also, if your piercer provided any specific instructions, be sure to follow them. The exact protocol might differ depending on the piercer and placement of your piercing. Additionally, according to Ciraldo, it might help to apply scar gel, which you can get at the drugstore without a prescription. The gel, which might contain a base of silicone or onion skin, may also be applied as a preventive measure—e.g., before a bump even forms.
However, if the bump hurts or develops a crust, you'll want to apply hydrogen peroxide twice a day to the area, says Ciraldo. And if it gets worse? The bump might indicate an infection. In this case, "consult a dermatologist, [as] you may need prescription topical or oral antibiotics," she notes.
How to care for a keloid.
To recap, "if you have a persistent bumpy scar, [it's] a keloid," says Ciraldo. This warrants a visit to the dermatologist, who will provide care instructions based on the keloid's size and location. For example, if you have a small keloid, your doctor might recommend applying a topical silicone gel. Other keloids might need steroid injections, which shrink the scar by breaking down excess collagen. Typically, according to Ciraldo, this "will be done in a series of injections spaced three to four weeks apart" or until the keloid shrinks or disappears. About 50 to 80% of keloids get smaller after being injected with steroids.
postbiotic body lotion
Ultra-hydrating formula that nourishes your skin barrier
A large keloid might need to be removed via surgery, according to NYU Langone Health. However, surgically removed keloids almost always come back, so this option is usually used with other treatments like steroid injections or a special dressing that places pressure on the keloid. (Pressure decreases blood flow in the area, thus preventing the keloid from redeveloping.) On that note, if the keloid is on an earlobe piercing, your dermatologist might suggest wearing a pressure earring to keep it at bay.
When to get help.
After getting a piercing of any kind, it's a good idea to monitor your skin. You should see a dermatologist ASAP if the area develops discoloration (red or darkened skin), swelling, pain, and/or crusting, according to Ciraldo. The same goes "if you have a painless bump that has lasted more than six weeks," she adds. Such a bump might be a keloid, which is easier to control with early care and treatment.
In general, a piercing bump will go away after about six weeks, while a keloid is permanent. The exception is a piercing bump caused by an infection, which will get worse over time. When in doubt, visit a doctor, especially if the bump is growing quickly or releasing pus and/or blood. This will help minimize the risk of piercing complications, as well as long-term side effects.
Kirsten Nunez, M.S. Contributing writer
Kirsten Nunez is a health and lifestyle journalist based in Beacon, New York. She has a Master of Science in Nutrition from Texas Woman's University and Bachelor of Science in Dietetics...
Bovine Collagen: Benefits & The Importance Of Grass-Fed
Nicotinamide Riboside: A Complete Guide To NR Supplements
Magnesium Glycinate: Uses Benefits Side Effects & More
https://www.mindbodygreen.com/articles/piercing-bump-vs-keloid-difference-and-how-to-treat-each


This study implemented a social media based content analysis to examine the subjective experiences and the current public perceptions of sexism in STEM fields. Participants included men and women who a) identified as either in STEM or not identified as in STEM and b) commented through Facebook on HuffPost Women articles about women in STEM. The analysis indicated that sexism remains an issue for women in STEM careers. Women in STEM identified several gender-based challenges that they have experienced; some participants discussed how they handled those challenges. Men both in and not in STEM were less likely to acknowledge and more likely to deny that sexism was a problem for women in STEM than were women participants. Though findings showed a high rate of supportive commentary from women, they also showed a substantial number of male commenters displaying overt sexism. The analysis helped identify a new form of sexism to the literature on subtle sexism: Threat to Masculinity. More specifically, both men and women were found to display overt sexism to men who supported women by utilizing gender based stereotypes to validate their claims and police gender roles. Findings from this study support the literature suggesting that sexism remains an issue that needs to be addressed; the analysis begins to build a theory about how such sexism is portrayed through social media commentary as an important arena of social and cultural debate. Current policies aimed at ending sexism/discrimination should be expanded to support and encourage women's participation in STEM careers.


text:
Q: i want to print first image record form Database if its found and stop the loop i have two tables in DB, one table have the Detail of person like name, place, country, city etc and 2nd table have multiple images records. in some records of images "images" filed is empty, so i want to print only one image. if the image filed is empty leave that and when the image is found? print it and stop the loop.
Here is my code:
 $sno= $resultvenue['Sno'];
 $searchphotolinks = mysql_query("SELECT `Image` FROM `Photos` Where `PersonID`='".$sno."' ORDER BY `Sno` ASC");
 while($linkphoto = mysql_fetch_array($searchphotolinks))
 {

 if($linkphoto['PhotosLink']!="")
 {
 ?>

 <a href="http://www.bigvenue.net/singlerecord/?id=<?php echo $sno;
 ?>"><img src="<?php echo $finalfile = $linkphoto['Image']; ?>" />

 <?php
 }
 }

A: Try this:
$finalfile = null;
while($linkphoto = mysql_fetch_array($searchphotolinks) && $finalfile != null){
    if($linkphoto['PhotosLink']!=""){
        $finalfile = $linkphoto['Image'];
        echo '
';
        echo "";
        echo "</div";
    }
}

This will stop the loop when you've set the $finalfile variable
break; would also work at the end of your if, and would be preferable, unless you plan on using $finalfile for something later


text:
dojo.provide("dijit.form.NumberSpinner");

dojo.require("dijit.form._Spinner");
dojo.require("dijit.form.NumberTextBox");

dojo.declare(
"dijit.form.NumberSpinner",
[dijit.form._Spinner, dijit.form.NumberTextBoxMixin],
{
	// summary:
	// extends NumberTextBox to add up/down arrows for incremental change to the value

	required: true,

	adjust: function(/* Object */ val, /*Number*/ delta){
		// summary: change Number val by the given amount
		var newval = val+delta;
		if(isNaN(val) || isNaN(newval)){ return val; }
		if((typeof this.constraints.max == "number") && (newval > this.constraints.max)){
			newval = this.constraints.max;
		}
		if((typeof this.constraints.min == "number") && (newval < this.constraints.min)){
			newval = this.constraints.min;
		}
		return newval;
	}
});


Planning a trip to Almeria? Make your search for flights much easier with tajawal! Offering the best prices on all flights to Almeria, you are sure the find the best flight option with tajawal. For further cities to extend your journey to, visit our Spain page.
Follow up your flight booking with a hotel room booking in Almeria. A comfortable bed is a must, so hurry and click through to our tajawal hotels page, and we will provide you the same easy service you have encountered all along.
If you are looking for a reliable and quick service, tajawal is the platform for you. Avail cheap flight tickets to Almeria and the best offers on hotels in Almeria, Book today!


text:
We competed in the Y4&5 small schools competitions at Saffron Lane, winning both. There were track races, discus, long jump, throwing and relays.
Our Y3&4 rugby team won the Oadby and Wigston league without losing a game.
Our hockey team qualified for the regional final, coming 2nd.
Our A and B tennis squads came 1st and 2nd at the Oadby and Wigston tournament.
The Y3&4 girls football team won a tournament they played in, scoring the most goals of any team.
Pages: 1 2 3 4 5 6 7 8 9 10 11
News and Events Navigation
Glenmere's 50th Anniversary
50th Anniversary Magazine
50th Anniversary Magazine Online
Cross Country League
Miss Strong's Article
Parent Questionnaires
Past Pupil Achievements
Sport Outside Of Glenmere


Comfortable private car service with ample room in a full size sedan for a relaxing ride.
Full-size SUV holds up to seven passengers with ample leg room. Great for business or pleasure.
Our Ford Transit transports small to mid-size groups. Luxury and comfort with plenty of room for luggage. Great for corporate groups or a wedding party.
Getting to an airport can be a stressful time – let us get you there on time, worry-free. And isn't it a great feeling arriving back at your hometown airport knowing a ride is waiting for you.
Your wedding day should be one of the most important days of your life. Let us take care of your transportation needs whether it's just for the bride and groom, your wedding party, or shuttling guests from their hotels to the venue.


The following newspaper, TV, magazine, and other media articles mention CTR research or include comments from CTR-affiliated researchers and faculty.
Members of the media: If you are looking for a subject matter expert and are on a deadline, please contact the Cockrell School of Engineering Office of Communications.
An archive of older press mentions can be found on the Internet Archive's Wayback Machine.


In this generation some of the top priorities that people have is eating healthy and nutritious food. In order to get it right and cook healthy dishes then you ought to have the right utensils. Here is what you stand to gain when you cook with the copper pots and pans.
With copper you will have the heat being able to spread evenly into the entire cookware. The point is that when you do this, you will have the food being cooked well. Some of the points that you should put in mind is that with this option you will not end up scorching the food as regulation the temperatures is something that is easy. the best part is that you will not have to worry about rust.
With the increasing pollution, one of the pointers is that one has to be careful with the type of environment that they get exposed to The important point is that you need to have a clean place for your family. The point that you should understand is that most of the damage that takes place in the lives of people is as a result of microorganism in the cookware. To keep your family safe, the best thing that you have to do is to use copper since it has antibacterial properties According to copper chef reviews they are also easy to clean.
They also help in keeping the digestive system healthy. when you are getting copper, some of the pointers that you should note is that it will help in detoxing your stomach. When you use the copper cookware you will get proper food absorption as it helps in regulating the kidney.
It is paramount for you to get the right product when you are going shopping. the one thing that you should note is that there are numerous people selling this product and the important point is that not all of them are reliable, Thus, you should take your time so that you can find out if the product is legit. You should not do the purchase without taking the time to read the comments about the products that the past client bought. The comments will help you find out if the products you bought are suitable or not.


text:
Justine Clay
Inside Houzz's acquisition of IvyMark
industry insider | Feb 6, 2018 |
By Melissa Studach
Just shy of its second year in business, workflow management platform IvyMark has been acquired by Houzz. Having garnered early success with more than 2,400 members to date, the IvyMark system will be a valuable component in empowering Houzz's 200,000 design professionals going forward, Houzz says.
Lee Rotenberg and Alexandra Schinasi, founders of IvyMark
While neither company is disclosing the terms of the acquisition (though sources estimate Houzz is paying $30-$40 million), one thing is for sure: There's more than just business behind this deal. The resemblances between the two digital natives were apparent during the initial meeting, both parties admit.
"When Houzz reached out and we got to know their team, company culture and vision for the industry, we knew it would be a perfect match," IvyMark co-founder Lee Rotenberg tells EAL. Likely the most coincidental commonality was that both Houzz and IvyMark have their engineering offices in Tel Aviv—just down the street from one another, in fact. "It was a no-brainer, and we knew this would be a dream come true for us, our team and our Ivy members," says Rotenberg.
Serial entrepreneurs Rotenberg and Alexandra Schinasi, previously the founders of artisan marketplace ArtSetters, launched IvyMark in 2016 to help streamline design firms' workflow. It didn't take long for the business management tool, which enables designers to source products, create estimates, send invoices and more, to gain momentum.
What set the system apart from other designer-minded workforce programs was its clean, simplified user interface and community-driven memberships—a title chosen intentionally by the IvyMark team, as opposed to the inclusivity-lacking alternative "users." In less than two years, that community has grown exponentially through IvyMark's online forum, trade magazine, educational webinars and member meetups across the U.S.
"IvyMark has built an incredible platform and team that align with our mission of providing the best experience for home renovation and design, by helping design professionals manage their business," says Alon Cohen, Houzz co-founder and president. "We are excited to bring the power of IvyMark's software and community to more professionals."
More than 2,400 design firms use IvyMark to manage business accounts.
For now, IvyMark will be integrated into Houzz's Industry Solutions team, Cohen tells EAL. Rotenberg and Schinasi will continue to run and build the business management system and brand within Houzz's trade channel.
"Our journey is just beginning with IvyMark," says Rotenberg. "Alex and I are thrilled to tackle this next chapter and disrupt the trade with that much more gusto with Houzz as our partner!"
The deal marks a nice transition for IvyMark founders, who had raised $2.9 million from investors including Disruptive VC, Pitango and NFX, and it had teams in New York, San Francisco and Tel Aviv.
Houzz is currently valued at $4 billion and has offices in London, Berlin, Sydney, Moscow, Tel Aviv and Tokyo.
Note to readers: February 9, 2018
Editor at Large was pleased to share the above news, however we deeply regret that we misread the agreed-upon time for posting (as EST, not PST) and released it before IvyMark could share the news with its members. We've been made aware that this error may have left some members feeling betrayed by the platform's founders. For that, we are sorry. We can confidently say that the IvyMark founders truly care about their members and have the best interests of their interior design community at heart.
Designer-friendly amenities are the focus of IMC's Americasmart renovation
Why you need to hire a technologist for your next project


Amazing Pictures Of organic Rice Cakes Baby - From the thousand Gallery on the net about organic rice cakes baby, we all filter the top libraries together with excellent quality completely for you, and of course,this photographs ,in actual fact, believed as one of pictures choices within our wonderful images gallery about Amazing Pictures Of organic Rice Cakes Baby. I am feeling you will think it's great. Beautiful photos (Organic Rice Cakes Baby Admirably organic Mini Rice Crackers with Apple From 10 Months) over can be branded along with: organic rice syrup, issued by simply Carolyn Hernandez at 2019-02-08 19:57:18. To get plenty models within Amazing Pictures Of organic Rice Cakes Baby pictures gallery please bear in mind that website hyperlink. If you enjoy with this post, then please share with your friends.


text:
Q: Getting data from a Barcode Scanner using PHP I've read a couple of posts here on the site and as far as I understand it, using PHP to get and process the information obtained through a Barcode Scanner is possible, however I'd like to ask just to make sure, is it recommended? are there any caveats I should be aware of?
EDIT
I don't know the software of the barcode scanner since I haven't had access to it, however I described how it works on the comments down here. the barcode generates a fixed number of characters so I guess I could use a javascript event listener =)

A: I've noticed a lot of stores use online or LAN POS sites to handle purchases. Typically, the add an item page will set focus to a text field devoted to the product's barcode. When the scanner scans the barcode it's been preconfigured to output the code to wherever the cursor is (in this case, the barcode text field). Most system then have a JavaScript event listener on the field that submits the new item when a barcode is entered (the field reaches a certain length). Of course this is all theory. If you want sample code, please provide more specifics on the scanner and the software it came with.


Your wedding should be beautiful and memorable, representative of you as a couple. You can find all that and more just a couple of hours away. Take a look at our top 6 reasons to have your wedding in Prague.
For any couple that appreciates European history and architecture, Prague, also known as 'The Golden city', offers all that and more, giving the city an air of charm and grace. Set on the romantic banks of the Vltava River, what could be more perfect for your fairytale wedding?
There is no shortage of astounding venues in Prague, with a number of diverse options available to suit every taste. Whether you're looking for a lavish ballroom in a grand hotel, an intimate reception in a magical garden, or a ceremony in a historical church, you're certain to find everything you desire.
The possibilities are endless, with venues and providers coming in at a less expensive price than other Western European countries, meaning you can have the wedding day of your dreams without breaking the bank.
Within easy reach of any European destination by car or rail, including regular flights to the international airport, Prague is perfectly accessible for couples and their family and friends from anywhere in the world.
Wedding providers in Prague often hold decades of experience in hosting extravagant events, being highly skilled in their art, giving you the chance to hire only the best for your day. This includes a wealth of caterers and restaurants who offer a wide range of world cuisine, happily adapting to their couples needs and wishes.
Being well-versed in a number of world languages serves the companies in Prague well, including English, German and Russian, with more languages being introduced every year. You should be able to communicate every detail during your wedding planning without a hitch.
Convinced? Get started on your wedding planning journey and take a look at our venues in Prague.


All orders are handmade and customers can expect to receive their item within 2-3 weeks, often times sooner, and never more than 30 days from the date of purchase.
All image-only orders are shipped rolled. Mounted and matted images come in a custom gift box.
Once your item is shipped you will receive a tracking number via e-mail to track your item and proximate arrival.
If your item arrives in poor condition or is not the item you requested, please view our return policy.
Note: Alaska, Hawaii and Canada are 50% more.
Please note: International orders depend on the product(s) ordered and the final destination. Orders shipped to metropolitan areas will be delivered quicker and more efficiently. Full postal code is required for shipping international. Please contact Tomas Spangler Photography for more information.