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

#include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h"

#include <algorithm>
#include <utility>

#include "build/build_config.h"
#include "build/buildflag.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/views/frame/browser_frame.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
#include "chrome/browser/ui/views/frame/opaque_browser_frame_view_platform_specific.h"
#include "chrome/browser/ui/views/tab_icon_view.h"
#include "chrome/browser/ui/views/tabs/new_tab_button.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/resources/grit/views_resources.h"
#include "ui/views/views_delegate.h"
#include "ui/views/window/frame_background.h"
#include "ui/views/window/frame_caption_button.h"
#include "ui/views/window/vector_icons/vector_icons.h"
#include "ui/views/window/window_shape.h"

#if defined(OS_LINUX)
#include "ui/views/controls/menu/menu_runner.h"
#endif

#if defined(OS_WIN)
#include "ui/display/win/screen_win.h"
#endif

using content::WebContents;

namespace {

class CaptionButtonBackgroundImageSource : public gfx::CanvasImageSource {
 public:
  CaptionButtonBackgroundImageSource(const gfx::ImageSkia& bg_image,
                                     int source_x,
                                     int source_y,
                                     int dest_width,
                                     int dest_height,
                                     bool draw_mirrored)
      : gfx::CanvasImageSource(bg_image.isNull() ? gfx::Size(1, 1)
                                                 : bg_image.size()),
        bg_image_(bg_image),
        source_x_(source_x),
        source_y_(source_y),
        dest_width_(dest_width),
        dest_height_(dest_height),
        draw_mirrored_(draw_mirrored) {}

  ~CaptionButtonBackgroundImageSource() override = default;

  void Draw(gfx::Canvas* canvas) override {
    if (bg_image_.isNull())
      return;

    gfx::ScopedCanvas scoped_canvas(canvas);

    if (draw_mirrored_) {
      canvas->Translate(gfx::Vector2d(dest_width_, 0));
      canvas->Scale(-1, 1);
    }

    canvas->TileImageInt(bg_image_, source_x_, source_y_, 0, 0, dest_width_,
                         dest_height_);
  }

 private:
  const gfx::ImageSkia bg_image_;
  int source_x_, source_y_;
  int dest_width_, dest_height_;
  bool draw_mirrored_;

  DISALLOW_COPY_AND_ASSIGN(CaptionButtonBackgroundImageSource);
};

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, public:

const char OpaqueBrowserFrameView::kClassName[] = "OpaqueBrowserFrameView";

OpaqueBrowserFrameView::OpaqueBrowserFrameView(
    BrowserFrame* frame,
    BrowserView* browser_view,
    OpaqueBrowserFrameViewLayout* layout)
    : BrowserNonClientFrameView(frame, browser_view),
      layout_(layout),
      window_icon_(nullptr),
      window_title_(nullptr),
      frame_background_(new views::FrameBackground()) {
  layout_->set_delegate(this);
  SetLayoutManager(std::unique_ptr<views::LayoutManager>(layout_));

  platform_observer_ =
      OpaqueBrowserFrameViewPlatformSpecific::Create(this, layout_);
}

OpaqueBrowserFrameView::~OpaqueBrowserFrameView() {}

void OpaqueBrowserFrameView::InitViews() {
  if (GetFrameButtonStyle() == FrameButtonStyle::kMdButton) {
    minimize_button_ = CreateFrameCaptionButton(
        views::CAPTION_BUTTON_ICON_MINIMIZE, HTMINBUTTON,
        views::kWindowControlMinimizeIcon);
    maximize_button_ = CreateFrameCaptionButton(
        views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, HTMAXBUTTON,
        views::kWindowControlMaximizeIcon);
    restore_button_ =
        CreateFrameCaptionButton(views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE,
                                 HTMAXBUTTON, views::kWindowControlRestoreIcon);
    close_button_ =
        CreateFrameCaptionButton(views::CAPTION_BUTTON_ICON_CLOSE, HTMAXBUTTON,
                                 views::kWindowControlCloseIcon);
  } else if (GetFrameButtonStyle() == FrameButtonStyle::kImageButton) {
    minimize_button_ =
        CreateImageButton(IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
                          IDR_MINIMIZE_BUTTON_MASK, VIEW_ID_MINIMIZE_BUTTON);
    maximize_button_ =
        CreateImageButton(IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
                          IDR_MAXIMIZE_BUTTON_MASK, VIEW_ID_MAXIMIZE_BUTTON);
    restore_button_ =
        CreateImageButton(IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
                          IDR_RESTORE_BUTTON_MASK, VIEW_ID_RESTORE_BUTTON);
    close_button_ =
        CreateImageButton(IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
                          IDR_CLOSE_BUTTON_MASK, VIEW_ID_CLOSE_BUTTON);
  }
  InitWindowCaptionButton(minimize_button_, IDS_ACCNAME_MINIMIZE,
                          VIEW_ID_MINIMIZE_BUTTON);
  InitWindowCaptionButton(maximize_button_, IDS_ACCNAME_MAXIMIZE,
                          VIEW_ID_MAXIMIZE_BUTTON);
  InitWindowCaptionButton(restore_button_, IDS_ACCNAME_RESTORE,
                          VIEW_ID_RESTORE_BUTTON);
  InitWindowCaptionButton(close_button_, IDS_ACCNAME_CLOSE,
                          VIEW_ID_CLOSE_BUTTON);

  // Initializing the TabIconView is expensive, so only do it if we need to.
  if (browser_view()->ShouldShowWindowIcon()) {
    window_icon_ = new TabIconView(this, this);
    window_icon_->set_is_light(true);
    window_icon_->SetID(VIEW_ID_WINDOW_ICON);
    AddChildView(window_icon_);
    window_icon_->Update();
  }

  web_app::AppBrowserController* controller =
      browser_view()->browser()->app_controller();
  if (controller) {
    set_web_app_frame_toolbar(AddChildView(
        std::make_unique<WebAppFrameToolbarView>(frame(), browser_view())));
  }

  // The window title appears above the web app frame toolbar (if present),
  // which surrounds the title with minimal-ui buttons on the left,
  // and other controls (such as the app menu button) on the right.
  window_title_ = new views::Label(browser_view()->GetWindowTitle());
  window_title_->SetVisible(browser_view()->ShouldShowWindowTitle());
  window_title_->SetSubpixelRenderingEnabled(false);
  window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  window_title_->SetID(VIEW_ID_WINDOW_TITLE);
  AddChildView(window_title_);
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, BrowserNonClientFrameView implementation:

gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStripRegion(
    const views::View* tabstrip) const {
  if (!tabstrip)
    return gfx::Rect();

  return layout_->GetBoundsForTabStripRegion(tabstrip->GetMinimumSize(),
                                             width());
}

int OpaqueBrowserFrameView::GetTopInset(bool restored) const {
  return browser_view()->IsTabStripVisible()
             ? layout_->GetTabStripInsetsTop(restored)
             : layout_->NonClientTopHeight(restored);
}

int OpaqueBrowserFrameView::GetThemeBackgroundXInset() const {
  return 0;
}

void OpaqueBrowserFrameView::UpdateThrobber(bool running) {
  if (window_icon_)
    window_icon_->Update();
}

gfx::Size OpaqueBrowserFrameView::GetMinimumSize() const {
  return layout_->GetMinimumSize(this);
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, views::NonClientFrameView implementation:

gfx::Rect OpaqueBrowserFrameView::GetBoundsForClientView() const {
  return layout_->client_view_bounds();
}

gfx::Rect OpaqueBrowserFrameView::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  return layout_->GetWindowBoundsForClientBounds(client_bounds);
}

int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
  int super_component = BrowserNonClientFrameView::NonClientHitTest(point);
  if (super_component != HTNOWHERE)
    return super_component;

  if (!bounds().Contains(point))
    return HTNOWHERE;

  int frame_component = frame()->client_view()->NonClientHitTest(point);

  // See if we're in the sysmenu region.  We still have to check the tabstrip
  // first so that clicks in a tab don't get treated as sysmenu clicks.
  if (ShouldShowWindowIcon() && frame_component != HTCLIENT) {
    gfx::Rect sysmenu_rect(IconBounds());
    // In maximized mode we extend the rect to the screen corner to take
    // advantage of Fitts' Law.
    if (IsFrameCondensed())
      sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom());
    sysmenu_rect = GetMirroredRect(sysmenu_rect);
    if (sysmenu_rect.Contains(point))
      return HTSYSMENU;
  }

  if (frame_component != HTNOWHERE)
    return frame_component;

  // Then see if the point is within any of the window controls.
  if (close_button_ && close_button_->GetVisible() &&
      close_button_->GetMirroredBounds().Contains(point))
    return HTCLOSE;
  if (restore_button_ && restore_button_->GetVisible() &&
      restore_button_->GetMirroredBounds().Contains(point))
    return HTMAXBUTTON;
  if (maximize_button_ && maximize_button_->GetVisible() &&
      maximize_button_->GetMirroredBounds().Contains(point))
    return HTMAXBUTTON;
  if (minimize_button_ && minimize_button_->GetVisible() &&
      minimize_button_->GetMirroredBounds().Contains(point))
    return HTMINBUTTON;

  views::WidgetDelegate* delegate = frame()->widget_delegate();
  if (!delegate) {
    LOG(WARNING) << "delegate is null, returning safe default.";
    return HTCAPTION;
  }

  // In the window corners, the resize areas don't actually expand bigger, but
  // the 16 px at the end of each edge triggers diagonal resizing.
  constexpr int kResizeAreaCornerSize = 16;
  int window_component = GetHTComponentForFrame(
      point, FrameTopBorderThickness(false), FrameBorderThickness(false),
      kResizeAreaCornerSize, kResizeAreaCornerSize, delegate->CanResize());
  // Fall back to the caption if no other component matches.
  return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
}

void OpaqueBrowserFrameView::GetWindowMask(const gfx::Size& size,
                                           SkPath* window_mask) {
  DCHECK(window_mask);

  if (IsFrameCondensed())
    return;

  views::GetDefaultWindowMask(
      size, frame()->GetCompositor()->device_scale_factor(), window_mask);
}

void OpaqueBrowserFrameView::ResetWindowControls() {
  BrowserNonClientFrameView::ResetWindowControls();
  restore_button_->SetState(views::Button::STATE_NORMAL);
  minimize_button_->SetState(views::Button::STATE_NORMAL);
  maximize_button_->SetState(views::Button::STATE_NORMAL);
  // The close button isn't affected by this constraint.
}

void OpaqueBrowserFrameView::UpdateWindowIcon() {
  if (window_icon_)
    window_icon_->SchedulePaint();
}

void OpaqueBrowserFrameView::UpdateWindowTitle() {
  if (!frame()->IsFullscreen() && ShouldShowWindowTitle()) {
    Layout();
    window_title_->SchedulePaint();
  }
}

void OpaqueBrowserFrameView::SizeConstraintsChanged() {}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, views::View overrides:

const char* OpaqueBrowserFrameView::GetClassName() const {
  return kClassName;
}

void OpaqueBrowserFrameView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
  node_data->role = ax::mojom::Role::kTitleBar;
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, views::ButtonListener implementation:

void OpaqueBrowserFrameView::ButtonPressed(views::Button* sender,
                                           const ui::Event& event) {
  if (sender == minimize_button_) {
    frame()->Minimize();
  } else if (sender == maximize_button_) {
    frame()->Maximize();
  } else if (sender == restore_button_) {
    frame()->Restore();
  } else if (sender == close_button_) {
    frame()->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked);
  } else if (sender == window_icon_) {
#if defined(OS_LINUX)
    // TODO(pbos): Figure out / document why this is Linux only. This needs a
    // comment.
    views::MenuRunner menu_runner(frame()->GetSystemMenuModel(),
                                  views::MenuRunner::HAS_MNEMONICS);
    menu_runner.RunMenuAt(
        browser_view()->GetWidget(), window_icon_->button_controller(),
        window_icon_->GetBoundsInScreen(), views::MenuAnchorPosition::kTopLeft,
        ui::MENU_SOURCE_MOUSE);
#endif
  }
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, TabIconView::TabContentsProvider implementation:

bool OpaqueBrowserFrameView::ShouldTabIconViewAnimate() const {
  // This function is queried during the creation of the window as the
  // TabIconView we host is initialized, so we need to null check the selected
  // WebContents because in this condition there is not yet a selected tab.
  WebContents* current_tab = browser_view()->GetActiveWebContents();
  return current_tab ? current_tab->IsLoading() : false;
}

gfx::ImageSkia OpaqueBrowserFrameView::GetFaviconForTabIconView() {
  views::WidgetDelegate* delegate = frame()->widget_delegate();
  if (!delegate) {
    LOG(WARNING) << "delegate is null, returning safe default.";
    return gfx::ImageSkia();
  }
  return delegate->GetWindowIcon();
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, OpaqueBrowserFrameViewLayoutDelegate implementation:

bool OpaqueBrowserFrameView::ShouldShowWindowIcon() const {
  views::WidgetDelegate* delegate = frame()->widget_delegate();
  return ShouldShowWindowTitleBar() && delegate &&
         delegate->ShouldShowWindowIcon();
}

bool OpaqueBrowserFrameView::ShouldShowWindowTitle() const {
  // |delegate| may be null if called from callback of InputMethodChanged while
  // a window is being destroyed.
  // See more discussion at http://crosbug.com/8958
  views::WidgetDelegate* delegate = frame()->widget_delegate();
  return ShouldShowWindowTitleBar() && delegate &&
         delegate->ShouldShowWindowTitle();
}

base::string16 OpaqueBrowserFrameView::GetWindowTitle() const {
  return frame()->widget_delegate()->GetWindowTitle();
}

int OpaqueBrowserFrameView::GetIconSize() const {
#if defined(OS_WIN)
  // This metric scales up if either the titlebar height or the titlebar font
  // size are increased.
  return display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSMICON);
#else
  // The icon never shrinks below 16 px on a side.
  const int kIconMinimumSize = 16;
  return std::max(gfx::FontList().GetHeight(), kIconMinimumSize);
#endif
}

gfx::Size OpaqueBrowserFrameView::GetBrowserViewMinimumSize() const {
  return browser_view()->GetMinimumSize();
}

bool OpaqueBrowserFrameView::ShouldShowCaptionButtons() const {
  return ShouldShowWindowTitleBar();
}

bool OpaqueBrowserFrameView::IsRegularOrGuestSession() const {
  return browser_view()->IsRegularOrGuestSession();
}

bool OpaqueBrowserFrameView::IsMaximized() const {
  return frame()->IsMaximized();
}

bool OpaqueBrowserFrameView::IsMinimized() const {
  return frame()->IsMinimized();
}

bool OpaqueBrowserFrameView::IsTabStripVisible() const {
  return browser_view()->IsTabStripVisible();
}

bool OpaqueBrowserFrameView::IsToolbarVisible() const {
  return browser_view()->IsToolbarVisible() &&
         !browser_view()->toolbar()->GetPreferredSize().IsEmpty();
}

int OpaqueBrowserFrameView::GetTabStripHeight() const {
  return browser_view()->GetTabStripHeight();
}

gfx::Size OpaqueBrowserFrameView::GetTabstripMinimumSize() const {
  return browser_view()->tabstrip()->GetMinimumSize();
}

int OpaqueBrowserFrameView::GetTopAreaHeight() const {
  const int non_client_top_height = layout_->NonClientTopHeight(false);
  if (!browser_view()->IsTabStripVisible())
    return non_client_top_height;
  return std::max(
      non_client_top_height,
      GetBoundsForTabStripRegion(browser_view()->tabstrip()).bottom() -
          GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP));
}

bool OpaqueBrowserFrameView::UseCustomFrame() const {
  return frame()->UseCustomFrame();
}

bool OpaqueBrowserFrameView::IsFrameCondensed() const {
  return BrowserNonClientFrameView::IsFrameCondensed() ||
         !ShouldShowCaptionButtons();
}

bool OpaqueBrowserFrameView::EverHasVisibleBackgroundTabShapes() const {
  return BrowserNonClientFrameView::EverHasVisibleBackgroundTabShapes();
}

OpaqueBrowserFrameView::FrameButtonStyle
OpaqueBrowserFrameView::GetFrameButtonStyle() const {
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
  return FrameButtonStyle::kMdButton;
#else
  return FrameButtonStyle::kImageButton;
#endif
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, protected:

// views::View:
void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
  TRACE_EVENT0("views.frame", "OpaqueBrowserFrameView::OnPaint");
  if (frame()->IsFullscreen())
    return;  // Nothing is visible, so don't bother to paint.

  const bool active = ShouldPaintAsActive();
  SkColor frame_color = GetFrameColor();
  window_title_->SetEnabledColor(
      GetCaptionColor(BrowserFrameActiveState::kUseCurrent));
  window_title_->SetBackgroundColor(frame_color);
  frame_background_->set_frame_color(frame_color);
  frame_background_->set_use_custom_frame(frame()->UseCustomFrame());
  frame_background_->set_is_active(active);
  frame_background_->set_incognito(browser_view()->IsIncognito());
  frame_background_->set_theme_image(GetFrameImage());
  const int y_inset =
      browser_view()->IsTabStripVisible()
          ? (ThemeProperties::kFrameHeightAboveTabs - GetTopInset(false))
          : 0;
  frame_background_->set_theme_image_y_inset(y_inset);
  frame_background_->set_theme_overlay_image(GetFrameOverlayImage());
  frame_background_->set_top_area_height(GetTopAreaHeight());

  if (GetFrameButtonStyle() == FrameButtonStyle::kMdButton) {
    for (auto* button :
         {minimize_button_, maximize_button_, restore_button_, close_button_}) {
      DCHECK_EQ(std::string(views::FrameCaptionButton::kViewClassName),
                button->GetClassName());
      views::FrameCaptionButton* frame_caption_button =
          static_cast<views::FrameCaptionButton*>(button);
      frame_caption_button->set_paint_as_active(active);
      frame_caption_button->SetBackgroundColor(frame_color);
    }
  }

  if (IsFrameCondensed())
    PaintMaximizedFrameBorder(canvas);
  else
    PaintRestoredFrameBorder(canvas);

  // The window icon and title are painted by their respective views.
  /* TODO(pkasting):  If this window is active, we should also draw a drop
   * shadow on the title.  This is tricky, because we don't want to hardcode a
   * shadow color (since we want to work with various themes), but we can't
   * alpha-blend either (since the Windows text APIs don't really do this).
   * So we'd need to sample the background color at the right location and
   * synthesize a good shadow color. */

  // Custom tab bar mode draws the toolbar as a unified part of the titlebar, so
  // it shouldn't have a client edge.
  if (!browser_view()->toolbar()->custom_tab_bar())
    PaintClientEdge(canvas);
}

///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, private:

views::Button* OpaqueBrowserFrameView::CreateFrameCaptionButton(
    views::CaptionButtonIcon icon_type,
    int ht_component,
    const gfx::VectorIcon& icon_image) {
  views::FrameCaptionButton* button =
      new views::FrameCaptionButton(this, icon_type, ht_component);
  button->SetImage(button->icon(), views::FrameCaptionButton::ANIMATE_NO,
                   icon_image);
  return button;
}

views::Button* OpaqueBrowserFrameView::CreateImageButton(int normal_image_id,
                                                         int hot_image_id,
                                                         int pushed_image_id,
                                                         int mask_image_id,
                                                         ViewID view_id) {
  views::ImageButton* button = new views::ImageButton(this);
  const ui::ThemeProvider* tp = frame()->GetThemeProvider();
  button->SetImage(views::Button::STATE_NORMAL,
                   tp->GetImageSkiaNamed(normal_image_id));
  button->SetImage(views::Button::STATE_HOVERED,
                   tp->GetImageSkiaNamed(hot_image_id));
  button->SetImage(views::Button::STATE_PRESSED,
                   tp->GetImageSkiaNamed(pushed_image_id));
  if (browser_view()->IsBrowserTypeNormal()) {
    // Get a custom processed version of the theme's background image so
    // that it appears to draw contiguously across all of the caption
    // buttons.
    const gfx::Size normal_image_size = GetThemeImageSize(normal_image_id);
    const gfx::ImageSkia processed_bg_image =
        GetProcessedBackgroundImageForCaptionButon(view_id, normal_image_size);

    // SetBackgroundImage immediately uses the provided ImageSkia pointer
    // (&processed_bg_image) to create a local copy, so it's safe for this
    // to be locally scoped.
    button->SetBackgroundImage(
        tp->GetColor(ThemeProperties::COLOR_CONTROL_BUTTON_BACKGROUND),
        (processed_bg_image.isNull() ? nullptr : &processed_bg_image),
        tp->GetImageSkiaNamed(mask_image_id));
  }
  return button;
}

void OpaqueBrowserFrameView::InitWindowCaptionButton(
    views::Button* button,
    int accessibility_string_id,
    ViewID view_id) {
  button->SetAccessibleName(l10n_util::GetStringUTF16(accessibility_string_id));
  button->SetID(view_id);
  AddChildView(button);
}

gfx::Size OpaqueBrowserFrameView::GetThemeImageSize(int image_id) {
  const ui::ThemeProvider* tp = frame()->GetThemeProvider();
  const gfx::ImageSkia* image = tp->GetImageSkiaNamed(image_id);

  return (image ? image->size() : gfx::Size());
}

int OpaqueBrowserFrameView::CalculateCaptionButtonBackgroundXOffset(
    ViewID view_id) {
  const int minimize_width = GetThemeImageSize(IDR_MINIMIZE).width();
  const int maximize_restore_width = GetThemeImageSize(IDR_MAXIMIZE).width();
  const int close_width = GetThemeImageSize(IDR_CLOSE).width();

  const bool is_rtl = base::i18n::IsRTL();

  switch (view_id) {
    case VIEW_ID_MINIMIZE_BUTTON:
      return (is_rtl ? close_width + maximize_restore_width : 0);
    case VIEW_ID_MAXIMIZE_BUTTON:
    case VIEW_ID_RESTORE_BUTTON:
      return (is_rtl ? close_width : minimize_width);
    case VIEW_ID_CLOSE_BUTTON:
      return (is_rtl ? 0 : minimize_width + maximize_restore_width);
    default:
      NOTREACHED();
      return 0;
  }
}

gfx::ImageSkia
OpaqueBrowserFrameView::GetProcessedBackgroundImageForCaptionButon(
    ViewID view_id,
    const gfx::Size& desired_size) {
  // We want the background image to tile contiguously across all of the
  // caption buttons, so we need to draw a subset of the background image,
  // with source offsets based on where this button is located relative to the
  // other caption buttons.  We also have to account for the image mirroring
  // that happens in RTL mode.  This is accomplished using a custom
  // ImageSource (defined at the top of the file).

  const ui::ThemeProvider* tp = frame()->GetThemeProvider();
  const gfx::ImageSkia* bg_image =
      tp->GetImageSkiaNamed(IDR_THEME_WINDOW_CONTROL_BACKGROUND);

  if (!bg_image)
    return gfx::ImageSkia();

  const bool is_rtl = base::i18n::IsRTL();
  const int bg_x_offset = CalculateCaptionButtonBackgroundXOffset(view_id);
  const int bg_y_offset = 0;
  std::unique_ptr<CaptionButtonBackgroundImageSource> source =
      std::make_unique<CaptionButtonBackgroundImageSource>(
          *bg_image, bg_x_offset, bg_y_offset, desired_size.width(),
          desired_size.height(), is_rtl);

  return gfx::ImageSkia(std::move(source), desired_size);
}

int OpaqueBrowserFrameView::FrameBorderThickness(bool restored) const {
  return layout_->FrameBorderThickness(restored);
}

int OpaqueBrowserFrameView::FrameTopBorderThickness(bool restored) const {
  return layout_->FrameTopBorderThickness(restored);
}

gfx::Rect OpaqueBrowserFrameView::IconBounds() const {
  return layout_->IconBounds();
}

bool OpaqueBrowserFrameView::ShouldShowWindowTitleBar() const {
  // Do not show the custom title bar if the system title bar option is enabled.
  if (!frame()->UseCustomFrame())
    return false;

  // Do not show caption buttons if the window manager is forcefully providing a
  // title bar (e.g., in Ubuntu Unity, if the window is maximized).
  return !views::ViewsDelegate::GetInstance()->WindowManagerProvidesTitleBar(
      IsMaximized());
}

void OpaqueBrowserFrameView::PaintRestoredFrameBorder(
    gfx::Canvas* canvas) const {
  const ui::ThemeProvider* tp = GetThemeProvider();
  frame_background_->SetSideImages(
      tp->GetImageSkiaNamed(IDR_WINDOW_LEFT_SIDE),
      tp->GetImageSkiaNamed(IDR_WINDOW_TOP_CENTER),
      tp->GetImageSkiaNamed(IDR_WINDOW_RIGHT_SIDE),
      tp->GetImageSkiaNamed(IDR_WINDOW_BOTTOM_CENTER));
  frame_background_->SetCornerImages(
      tp->GetImageSkiaNamed(IDR_WINDOW_TOP_LEFT_CORNER),
      tp->GetImageSkiaNamed(IDR_WINDOW_TOP_RIGHT_CORNER),
      tp->GetImageSkiaNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER),
      tp->GetImageSkiaNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER));
  frame_background_->PaintRestored(canvas, this);

  // Note: When we don't have a toolbar, we need to draw some kind of bottom
  // edge here.  Because the App Window graphics we use for this have an
  // attached client edge and their sizing algorithm is a little involved, we do
  // all this in PaintRestoredClientEdge().
}

void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(
    gfx::Canvas* canvas) const {
  frame_background_->set_maximized_top_inset(GetTopInset(true) -
                                             GetTopInset(false));
  frame_background_->PaintMaximized(canvas, this);
}

void OpaqueBrowserFrameView::PaintClientEdge(gfx::Canvas* canvas) const {
  const bool tabstrip_visible = browser_view()->IsTabStripVisible();
  const gfx::Rect client_bounds =
      layout_->CalculateClientAreaBounds(width(), height());

  // In maximized mode, the only edge to draw is the top one, so we're done.
  if (IsFrameCondensed())
    return;

  int y = client_bounds.y();
  const gfx::Rect toolbar_bounds = browser_view()->toolbar()->bounds();
  if (tabstrip_visible) {
    // The client edges start at the top of the toolbar.
    y += toolbar_bounds.y();
  }

  // For popup windows, draw location bar sides.
  const SkColor location_bar_border_color =
      browser_view()->toolbar()->location_bar()->GetOpaqueBorderColor();
  if (!tabstrip_visible && IsToolbarVisible()) {
    gfx::Rect side(client_bounds.x() - kClientEdgeThickness, y,
                   kClientEdgeThickness, toolbar_bounds.height());
    canvas->FillRect(side, location_bar_border_color);
    side.Offset(client_bounds.width() + kClientEdgeThickness, 0);
    canvas->FillRect(side, location_bar_border_color);
  }
}


text:
// flow-typed signature: 2725aabd728967b52aa66442d40991e4
// flow-typed version: <<STUB>>/uglify-js_v^2.8.22/flow_v0.44.2

/**
 * This is an autogenerated libdef stub for:
 *
 *   'uglify-js'
 *
 * Fill this stub out by replacing all the `any` types.
 *
 * Once filled out, we encourage you to share your work with the
 * community by sending a pull request to:
 * https://github.com/flowtype/flow-typed
 */

declare module 'uglify-js' {
  declare module.exports: any;
}

/**
 * We include stubs for each file inside this npm package in case you need to
 * require those files directly. Feel free to delete any files that aren't
 * needed.
 */
declare module 'uglify-js/bin/extract-props' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/ast' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/compress' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/mozilla-ast' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/output' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/parse' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/propmangle' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/scope' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/sourcemap' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/transform' {
  declare module.exports: any;
}

declare module 'uglify-js/lib/utils' {
  declare module.exports: any;
}

declare module 'uglify-js/tools/exports' {
  declare module.exports: any;
}

declare module 'uglify-js/tools/node' {
  declare module.exports: any;
}

// Filename aliases
declare module 'uglify-js/bin/extract-props.js' {
  declare module.exports: $Exports<'uglify-js/bin/extract-props'>;
}
declare module 'uglify-js/lib/ast.js' {
  declare module.exports: $Exports<'uglify-js/lib/ast'>;
}
declare module 'uglify-js/lib/compress.js' {
  declare module.exports: $Exports<'uglify-js/lib/compress'>;
}
declare module 'uglify-js/lib/mozilla-ast.js' {
  declare module.exports: $Exports<'uglify-js/lib/mozilla-ast'>;
}
declare module 'uglify-js/lib/output.js' {
  declare module.exports: $Exports<'uglify-js/lib/output'>;
}
declare module 'uglify-js/lib/parse.js' {
  declare module.exports: $Exports<'uglify-js/lib/parse'>;
}
declare module 'uglify-js/lib/propmangle.js' {
  declare module.exports: $Exports<'uglify-js/lib/propmangle'>;
}
declare module 'uglify-js/lib/scope.js' {
  declare module.exports: $Exports<'uglify-js/lib/scope'>;
}
declare module 'uglify-js/lib/sourcemap.js' {
  declare module.exports: $Exports<'uglify-js/lib/sourcemap'>;
}
declare module 'uglify-js/lib/transform.js' {
  declare module.exports: $Exports<'uglify-js/lib/transform'>;
}
declare module 'uglify-js/lib/utils.js' {
  declare module.exports: $Exports<'uglify-js/lib/utils'>;
}
declare module 'uglify-js/tools/exports.js' {
  declare module.exports: $Exports<'uglify-js/tools/exports'>;
}
declare module 'uglify-js/tools/node.js' {
  declare module.exports: $Exports<'uglify-js/tools/node'>;
}

redpajama_set_name: RedPajamaGithub


text:
from tower import ugettext_lazy as _

class DEVICE_DESKTOP(object):
    id = 1
    name = _(u'Desktop')
    class_name = 'desktop'
    api_name = 'desktop'

class DEVICE_MOBILE(object):
    id = 2
    name = _(u'Firefox Mobile')
    class_name = 'android-mobile'
    api_name = 'android-mobile'

class DEVICE_TABLET(object):
    id = 3
    name = _(u'Firefox Tablet')
    class_name = 'android-tablet'
    api_name = 'android-tablet'

class DEVICE_GAIA(object):
    id = 4
    name = _(u'Firefox OS')
    class_name = 'firefoxos'
    api_name = 'firefoxos'

DEVICE_TYPE_LIST = [DEVICE_DESKTOP, DEVICE_MOBILE, DEVICE_TABLET, DEVICE_GAIA]
DEVICE_TYPES = dict((d.id, d) for d in DEVICE_TYPE_LIST)
REVERSE_DEVICE_LOOKUP = dict((d.id, d.api_name) for d in DEVICE_TYPE_LIST)
DEVICE_LOOKUP = dict((d.api_name, d) for d in DEVICE_TYPE_LIST)

# For search and feed.
DEVICE_CHOICES_IDS = {
    'desktop': DEVICE_DESKTOP.id,
    'mobile': DEVICE_MOBILE.id,
    'tablet': DEVICE_TABLET.id,
    'firefoxos': DEVICE_GAIA.id,
}

def get_device(request):
    # Fireplace sends `dev` and `device`. See the API docs. When `dev` is
    # 'android' we also need to check `device` to pick a device object.
    dev = request.GET.get('dev')
    device = request.GET.get('device')

    if dev == 'android' and device:
        dev = '%s-%s' % (dev, device)

    return DEVICE_LOOKUP.get(dev)

def get_device_id(request):
    return getattr(get_device(request), 'id', None)


text:
pbrt example scene
==================

This file contains a single example scene, ``killeroo-simple``, which is
mentioned in the exercise at the end of Chapter 1.  For many more scenes
(that are also much more interesting), see the [pbrt-v3 scenes
page](http://pbrt.org/scenes-v3.html) on the pbrt website.


text:
require 'rails_helper'
RSpec.describe SkillPolicy do
  describe 'permissions' do
    subject { SkillPolicy.new current_user, skill }

    context 'as a Super Administrator' do
      let(:current_user) { create :super_admin }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on any existing skill' do
        let(:skill) { create :skill }
        it { is_expected.to permit_action :show }
        it { is_expected.to permit_action :destroy }
        it { is_expected.to permit_action :undelete }
      end

      context 'on a new skill' do
        let(:skill) { build :skill }
        it { is_expected.to permit_new_and_create_actions }
      end
    end

    context 'as a Global Administrator' do
      let(:current_user) { create :global_admin }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on any existing skill' do
        let(:skill) { create :skill }
        it { is_expected.to permit_action :show }
        it { is_expected.to permit_action :destroy }
        it { is_expected.to permit_action :undelete }
      end

      context 'on a new skill' do
        let(:skill) { build :skill }
        it { is_expected.to permit_new_and_create_actions }
      end
    end

    context 'as a Global Guest' do
      let(:current_user) { create :global_guest }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on any existing skill' do
        let(:skill) { create :skill }
        it { is_expected.to permit_action :show }
        it { is_expected.to forbid_action :destroy }
        it { is_expected.to forbid_action :undelete }
      end

      context 'on a new skill' do
        let(:skill) { build :skill }
        it { is_expected.to forbid_new_and_create_actions }
      end
    end

    context 'as a Global Researcher' do
      let(:current_user) { create :global_researcher }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on any existing skill' do
        let(:skill) { create :skill }
        it { is_expected.to permit_action :show }
        it { is_expected.to forbid_action :destroy }
        it { is_expected.to forbid_action :undelete }
      end

      context 'on a new skill' do
        let(:skill) { build :skill }
        it { is_expected.to forbid_new_and_create_actions }
      end
    end

    context 'as a Local Administrator' do
      let(:org) { create :organization }
      let(:current_user) { create :admin_of, organization: org }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on a skill inside own\'s organization' do
        let(:skill) { create :skill, organization: org }
        it { is_expected.to permit_action :show }
        it { is_expected.to permit_action :destroy }
        it { is_expected.to permit_action :undelete }
      end

      context 'on a skill outside of own\'s organization' do
        let(:skill) { create :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :show }
        it { is_expected.to forbid_action :destroy }
        it { is_expected.to forbid_action :undelete }
      end

      context 'on a new skill in own organization' do
        let(:skill) { build :skill, organization: org }
        it { is_expected.to permit_new_and_create_actions }
      end

      context 'on a new skill outside of own organization' do
        let(:skill) { build :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :create }
      end

      context 'on a skill belonging to a different organization, but used in the subject from own organization' do
        let(:subject1) { create :subject, organization: org }
        let(:skill) { create :skill_in_subject, organization: create(:organization), subject: subject1 }

        it { is_expected.to permit_action :show }
        it { is_expected.to forbid_action :destroy }
        it { is_expected.to forbid_action :undelete }
      end
    end

    context 'as a Local Teacher' do
      let(:org) { create :organization }
      let(:current_user) { create :teacher_in, organization: org }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on a skill inside own\'s organization' do
        let(:skill) { create :skill, organization: org }
        it { is_expected.to permit_action :show }
      end

      context 'on a skill outside of own\'s organization' do
        let(:skill) { create :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :show }
      end

      context 'on a new skill in own organization' do
        let(:skill) { build :skill, organization: org }
        it { is_expected.to forbid_new_and_create_actions }
      end

      context 'on a new skill outside of own organization' do
        let(:skill) { build :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :create }
      end

      context 'on a skill belonging to a different organization, but used in the subject from own organization' do
        let(:subject1) { create :subject, organization: org }
        let(:skill) { create :skill_in_subject, organization: create(:organization), subject: subject1 }

        it { is_expected.to permit_action :show }
      end
    end

    context 'as a Local Guest' do
      let(:org) { create :organization }
      let(:current_user) { create :guest_in, organization: org }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on a skill inside own\'s organization' do
        let(:skill) { create :skill, organization: org }
        it { is_expected.to permit_action :show }
      end

      context 'on a skill outside of own\'s organization' do
        let(:skill) { create :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :show }
      end

      context 'on a new skill in own organization' do
        let(:skill) { build :skill, organization: org }
        it { is_expected.to forbid_new_and_create_actions }
      end

      context 'on a new skill outside of own organization' do
        let(:skill) { build :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :create }
      end

      context 'on a skill belonging to a different organization, but used in the subject from own organization' do
        let(:subject1) { create :subject, organization: org }
        let(:skill) { create :skill_in_subject, organization: create(:organization), subject: subject1 }

        it { is_expected.to permit_action :show }
      end
    end

    context 'as a Local Researcher' do
      let(:org) { create :organization }
      let(:current_user) { create :researcher_in, organization: org }

      context 'on a Skill Resource' do
        let(:skill) { Skill }
        it { is_expected.to permit_action :index }
      end

      context 'on a skill inside own\'s organization' do
        let(:skill) { create :skill, organization: org }
        it { is_expected.to permit_action :show }
      end

      context 'on a skill outside of own\'s organization' do
        let(:skill) { create :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :show }
      end

      context 'on a new skill in own organization' do
        let(:skill) { build :skill, organization: org }
        it { is_expected.to forbid_new_and_create_actions }
      end

      context 'on a new skill outside of own organization' do
        let(:skill) { build :skill, organization: create(:organization) }
        it { is_expected.to forbid_action :create }
      end

      context 'on a skill belonging to a different organization, but used in the subject from own organization' do
        let(:subject1) { create :subject, organization: org }
        let(:skill) { create :skill_in_subject, organization: create(:organization), subject: subject1 }

        it { is_expected.to permit_action :show }
      end
    end
  end

  describe 'scope' do
    RSpec.shared_examples :global_user_skill_scope do
      subject(:result) { SkillPolicy::Scope.new(current_user, Skill).resolve }
      let(:org1) { create :organization }
      let(:org2) { create :organization }
      let(:skills_in_org1) { create_list :skill, 3, organization: org1 }
      let(:skills_in_org2) { create_list :skill, 3, organization: org2 }

      it 'returns all skills from the first organization' do
        expect(result).to include(*skills_in_org1)
      end

      it 'returns all skills from second organization' do
        expect(result).to include(*skills_in_org2)
      end
    end

    RSpec.shared_examples :local_user_skill_scope do
      subject(:result) { SkillPolicy::Scope.new(current_user, Skill).resolve }
      let!(:org2) { create :organization }
      let!(:skill_subject) { create :subject, organization: org }
      let!(:skills_in_org) { create_list :skill, 3, organization: org }
      let!(:skills_in_org2) { create_list :skill, 3, organization: org2 }
      let!(:skills_in_org2_used_in_subject) { create_list :skill_in_subject, 3, organization: org2, subject: skill_subject }

      it 'includes all skills from the first organization' do
        expect(result).to include(*skills_in_org)
      end

      it 'does not include skills from the second organization' do
        expect(result).not_to include(*skills_in_org2)
      end

      it 'includes skills from the second organization that are used in the subject from first organization' do
        expect(result).to include(*skills_in_org2_used_in_subject)
      end
    end

    context 'As a Super Administrator' do
      let(:current_user) { create :super_admin }
      it_behaves_like :global_user_skill_scope
    end

    context 'As a Global Administrator' do
      let(:current_user) { create :global_admin }
      it_behaves_like :global_user_skill_scope
    end

    context 'As a Global Guest' do
      let(:current_user) { create :global_guest }
      it_behaves_like :global_user_skill_scope
    end

    context 'As a Global Researcher' do
      let(:current_user) { create :global_researcher }
      it_behaves_like :global_user_skill_scope
    end

    context 'As a Local Administrator' do
      let(:org) { create :organization }
      let(:current_user) { create :admin_of, organization: org }
      it_behaves_like :local_user_skill_scope
    end

    context 'As a Local Teacher' do
      let(:org) { create :organization }
      let(:current_user) { create :teacher_in, organization: org }
      it_behaves_like :local_user_skill_scope
    end

    context 'As a Local Guest' do
      let(:org) { create :organization }
      let(:current_user) { create :guest_in, organization: org }
      it_behaves_like :local_user_skill_scope
    end

    context 'As a Local Researcher' do
      let(:org) { create :organization }
      let(:current_user) { create :researcher_in, organization: org }
      it_behaves_like :local_user_skill_scope
    end

    context 'As a User with roles in multiple organizations' do
      subject(:result) { SkillPolicy::Scope.new(current_user, Skill).resolve }

      let(:org1) { create :organization }
      let(:org2) { create :organization }
      let(:org3) { create :organization }
      let(:current_user) do
        u = create :admin_of, organization: org1
        u.add_role :teacher, org2
        u
      end

      let(:skills_in_org1) { create_list :skill, 3, organization: org1 }
      let(:skills_in_org2) { create_list :skill, 3, organization: org2 }
      let(:skills_in_org3) { create_list :skill, 3, organization: org3 }

      it 'includes all skills from the first organization' do
        expect(result).to include(*skills_in_org1)
      end

      it 'includes all skills from the second organization' do
        expect(result).to include(*skills_in_org2)
      end

      it 'does not include skills from a different organization' do
        expect(result).not_to include(*skills_in_org3)
      end
    end
  end
end


text:
require 'spec/expectations'

Given /^I fail$/ do
  raise "BOOM (this is expected)"
end

Given /^I pass$/ do
end

module HookChecks
  def check_failed(scenario)
    scenario.should be_failed
    scenario.should_not be_passed
    scenario.exception.message.should == "BOOM (this is expected)"
  end

  def check_undefined(scenario)
    scenario.should_not be_failed
    scenario.should_not be_passed
  end

  def check_passed(scenario)
    scenario.should_not be_failed
    scenario.should be_passed
  end
end

World(HookChecks)

After('@272_failed') do |scenario|
  check_failed(scenario)
end

After('@272_undefined') do |scenario|
  check_undefined(scenario)
end

After('@272_passed') do |scenario|
  check_passed(scenario)
end

counter = 0
After('@272_outline') do |scenario|
  case(counter)
    when 0
      check_failed(scenario)
    when 1
      check_undefined(scenario)
    when 2
      check_passed(scenario)
  end
  counter +=1
end


text:
import autosize from 'autosize';
import striptags from 'striptags';
import Utils from './SurveyUtils.js';

const markdown = require('../../utils/markdown_it.js').default();

const CONDITIONAL_ANSWERS_CHANGED = 'ConditionalAnswersChanged';
const CONDITIONAL_COMPARISON_OPERATORS = `\
<option>></option>
<option>>=</option>
<option><</option>
<option><=</option>\
`;

const SurveyAdmin = {
  async init() {
    await import('jquery-ui/ui/widgets/sortable');
    await import('jquery-ui/ui/widgets/tabs');
    $('[data-tabs]').tabs();
    autosize($('textarea'));
    this.cacheSelectors();
    this.course_data = Boolean(this.$course_data_populate_checkbox.attr('checked'));
    this.initSortableQuestions();
    this.initSortableQuestionGroups();
    this.listeners();
    this.initConditionals();
    this.initSearchableList();
    this.initMarkdown();
  },

  listeners() {
    this.handleQuestionType();
    this.$clear_conditional_button.on('click', $.proxy(this, 'clearConditional'));
    this.$conditional_question_select.on('change', $.proxy(this, 'handleConditionalSelect'));
    this.$conditional_value_select.on('change', $.proxy(this, 'handleConditionalAnswerSelect'));
    this.$question_type_select.on('change', $.proxy(this, 'handleQuestionType'));
    this.$add_conditional_button.on('click', $.proxy(this, 'addConditional'));
    this.$course_data_populate_checkbox.on('change', $.proxy(this, 'handleCourseDataCheckboxChange'));
    this.$follow_up_question_checkbox.on('change', $.proxy(this, 'handleFollowUpCheckboxChange'));
    this.$matrix_options_checkbox.on('change', $.proxy(this, 'handleMatrixCheckboxChange'));
    return this.$conditional_option_checkbox.on('change', $.proxy(this, 'handleConditionalCheckboxChange'));
  },

  cacheSelectors() {
    this.$document = $(document);
    this.$question_type_select = $('#question_type');
    this.$question_form_options = $('[data-question-options]');
    this.$question_text_input = $('[data-question-text]');
    this.$question_text_editor = $('[data-question-text-editor]');
    this.$conditional_operator = $('[data-conditional-operator]');
    this.$conditional_operator_select = $('[data-conditional-operator-select]');
    this.$add_conditional_button = $('[data-add-conditional]');
    this.$clear_conditional_button = $('[data-clear-conditional]');
    this.$conditional_question_select = $('[data-conditional-select]');
    this.$conditional_value_select = $('[data-conditional-value-select]');
    this.$conditional_input_field = $('[data-conditional-field-input]');
    this.$conditional_value_number_field = $('[data-conditional-value-number]');
    this.$question_type_options = $('[data-question-type-options]');
    this.$question_type_options_hide_if = $('[question-type-options-hide-if]');
    this.$question_type_fields = $('[data-question-type-field]');
    this.$course_data_populate_checkbox = $('[data-course-data-populate-checkbox]');
    this.$follow_up_question_checkbox = $('[data-follow-up-question-checkbox]');
    this.$conditional_option_checkbox = $('[data-conditional-option-checkbox]');
    this.$matrix_options_checkbox = $('[data-matrix-checkbox]');
    this.$course_data_type_select = $('#question_course_data_type');
    this.$answer_options = $('[data-answer-options]');
    return this.$range_input_options = $('[data-question-type-options="RangeInput"');
  },

  initSortableQuestions() {
    const $sortable = $('[data-sortable-questions]');
    const questionGroupId = $sortable.data('sortable-questions');
    return $sortable.sortable({
      axis: 'y',
      items: '.row--survey-question',
      // containment: 'parent'
      scroll: false,
      cursor: 'move',
      sort(e, ui) {
        return ui.item.addClass('active-item-shadow');
      },
      stop(e, ui) {
        return ui.item.removeClass('active-item-shadow');
      },
      update(e, ui) {
        const itemId = ui.item.data('item-id');
        const position = ui.item.index() + 1; // acts_as_list defaults to start at 1
        return $.ajax({
          type: 'PUT',
          url: '/surveys/question_position',
          dataType: 'json',
          data: { question_group_id: questionGroupId, id: itemId, position }
        });
      }
    });
  },

  initSortableQuestionGroups() {
    const $sortable = $('[data-sortable-question-groups]');
    const surveyId = $sortable.data('sortable-question-groups');
    return $sortable.sortable({
      axis: 'y',
      items: '.question-group-row',
      scroll: false,
      cursor: 'move',
      sort(e, ui) {
        return ui.item.addClass('active-item-shadow');
      },
      stop(e, ui) {
        return ui.item.removeClass('active-item-shadow');
      },
      update(e, ui) {
        const itemId = ui.item.data('item-id');
        const position = ui.item.index() + 1; // acts_as_list defaults to start at 1
        return $.ajax({
          type: 'POST',
          url: '/surveys/update_question_group_position',
          dataType: 'json',
          data: { survey_id: surveyId, question_group_id: itemId, position }
        });
      }
    });
  },

  handleQuestionType() {
    if (!this.$question_type_select.length) { return; }
    const type = this.$question_type_select.val().split('::').pop();
    this.$question_type_options.addClass('hidden');
    switch (type) {
      case 'Text':
        return this.clearRangeInputOptions();
      case 'RangeInput':
        this.hideQuestionTypes('RangeInput');
        return this.showQuestionTypes('RangeInput');
      default:
        this.hideQuestionTypes(type);
        this.showQuestionTypes(type);
        return this.clearRangeInputOptions();
    }
  },

  hideQuestionTypes(string) {
    return $(`[data-question-type-options-hide-if*='${string}']`).addClass('hidden');
  },

  showQuestionTypes(string) {
    $(`[data-question-type-options*='${string}']`).removeClass('hidden');
    if (this.course_data) { this.$answer_options.addClass('hidden'); }

    switch (string) {
      case 'Select': case 'Checkbox': case 'Radio':
        if (!this.course_data) { return this.$answer_options.removeClass('hidden'); }
        break;
      case 'Long': case 'Short':
        return this.$answer_options.addClass('hidden');
      default:
        // no default
    }
  },

  handleConditionalSelect(e) {
    const id = e.target.value;
    if (id !== '') {
      this.conditional = {};
      this.conditional.question_id = id;
      return this.getQuestion(id);
    }
  },

  clearRangeInputOptions() {
    return this.$range_input_options.find('input').val('');
  },

  getQuestion(id) {
    return $.ajax({
      url: `/surveys/question_group_question/${id}`,
      method: 'get',
      dataType: 'json',
      contentType: 'application/json',
      success: $.proxy(this, 'handleConditionalQuestionSelect')
    });
  },

  handleConditionalQuestionSelect(e) {
    this.clearConditionalOperatorAndValue();
    switch (e.question_type) {
      case 'long': case 'short':
        return this.textConditional(e.question);
      case 'rangeinput':
        return this.comparisonConditional(e.question);
      default:
        return this.multipleChoiceConditional(e.question);
    }
  },

  handleCourseDataCheckboxChange({ target }) {
    const $courseData = $('[data-question-type-field="course_data"]');
    if (target.checked) {
      this.course_data = true;
      $courseData.removeClass('hidden');
      return this.$answer_options.addClass('hidden');
    }
    this.course_data = false;
    this.$course_data_type_select.prop('selectedIndex', 0);
    $courseData.addClass('hidden');
    return this.$answer_options.removeClass('hidden');
  },

  handleFollowUpCheckboxChange({ target }) {
    const $option = $('[data-question-type-field="follow_up_question"]');
    if (target.checked) {
      return $option.removeClass('hidden');
    }
    return $option.addClass('hidden');
  },

  handleMatrixCheckboxChange({ target }) {
    const $option = $('[data-question-type-field="matrix"]');
    if (target.checked) {
      return $option.removeClass('hidden');
    }
    return $option.addClass('hidden');
  },

  handleConditionalCheckboxChange({ target }) {
    const $option = $('[data-conditional-options]');
    if (target.checked) {
      return $option.removeClass('hidden');
    }
    return $option.addClass('hidden');
  },

  textConditional() {
    this.$conditional_operator.text('is present');
    return this.addPresenceConditional();
  },

  comparisonConditional() {
    this.$conditional_operator_select.append(CONDITIONAL_COMPARISON_OPERATORS).removeClass('hidden');
    this.$conditional_value_number_field.removeClass('hidden');
    return this.$conditional_value_number_field.on('blur', (e) => {
      let conditionalString = '';
      conditionalString += `${this.$conditional_question_select.val()}|`;
      conditionalString += `${this.$conditional_operator_select.val()}|`;
      conditionalString += e.target.value;
      return this.$conditional_input_field.val(conditionalString);
    });
  },

  multipleChoiceConditional(question) {
    this.$conditional_operator.text('=');
    this.conditional.operator = '=';
    this.$clear_conditional_button.removeClass('hidden');
    const answers = question.answer_options.split('\n');
    this.$conditional_value_select.append("<option value='nil' slelected>Select an Answer</option>");
    answers.map((answer) => {
      const answerValue = answer.trim();
      return this.$conditional_value_select.append(`<option value='${this.sanitizeAnswerValue(answerValue)}'>${answerValue}</option>`);
    });
    this.$conditional_value_select.removeClass('hidden');
    return this.$document.trigger(CONDITIONAL_ANSWERS_CHANGED);
  },

  sanitizeAnswerValue(string) {
    return striptags(string).replace('\'', ''').replace('"', '"').split(' ').join('_');
  },
  // string.replace('\'', ''').replace('\"', '"')

  handleConditionalAnswerSelect({ target }) {
    if (target.value !== 'nil') {
      this.conditional.answer_value = target.value;
      return this.addMultiConditional();
    }
  },

  initConditionals() {
    return $('[data-conditional]').each((i, conditionalRow) => {
      const $row = $(conditionalRow);
      const string = $row.data('conditional');
      if (string === '') { return; }
      const { question_id, operator, value } = Utils.parseConditionalString(string);
      switch (operator) {
        case '<': case '<=': case '>': case '>=':
          // eslint-disable-next-line camelcase
          $row.find('select').val(`${question_id}`);
          this.$conditional_operator_select.append(CONDITIONAL_COMPARISON_OPERATORS).removeClass('hidden');
          this.$conditional_operator_select.val(operator).trigger('change').removeClass('hidden');
          return this.$conditional_value_number_field.val(value).removeClass('hidden');
        default:
          this.$conditional_operator.text(operator);
          this.$document.on(CONDITIONAL_ANSWERS_CHANGED, () => {
            this.$conditional_value_select.val(value).trigger('change');
            return this.$document.off(CONDITIONAL_ANSWERS_CHANGED);
          });
          // eslint-disable-next-line camelcase
          return $row.find('select').val(`${question_id}`).trigger('change');
      }
    });
  },

  addPresenceConditional() {
    return this.$conditional_input_field.val(`${this.$conditional_question_select.val()}|*presence`);
  },

  addMultiConditional(e) {
    if (e) { e.preventDefault(); }
    let conditionalString = '';
    conditionalString += `${this.$conditional_question_select.val()}|`;
    conditionalString += `${this.$conditional_operator.text()}|`;
    conditionalString += `${this.$conditional_value_select.val()}|multi`;
    return this.$conditional_input_field.val(conditionalString);
  },

  clearConditional(e) {
    if (e) { e.preventDefault(); }
    this.$conditional_operator.text('');
    this.$conditional_question_select.prop('selectedIndex', 0);
    this.clearConditionalOperatorAndValue();
    return this.$conditional_input_field.val(null);
  },

  clearConditionalOperatorAndValue() {
    this.$conditional_value_select.addClass('hidden').prop('selectedIndex', 0);
    this.$clear_conditional_button.addClass('hidden');
    this.$conditional_value_number_field.val('').addClass('hidden');
    return this.$conditional_operator_select.off('blur').empty().addClass('hidden');
  },

  initSearchableList() {
    const options = {
      valueNames: ['name', 'status', 'author'],
    };
    const listObj = new List('searchable-list', options); // eslint-disable-line no-undef
    return listObj;
  },

  initMarkdown() {
    const updateMarkdownTabs = function (source, $preview, $source) {
      $preview.html(source);
      return $source.text(source);
    };

    $('[data-markdown-source]').each((i, text) => {
      const $text = $(text);
      const id = $text.data('markdown-source');
      const $preview = $(`[data-markdown-preview='${id}']`);
      const $source = $(`[data-markdown-source-view='${id}']`);
      const update = function () {
        const html = markdown.render($text.val());
        return updateMarkdownTabs(html, $preview, $source);
      };
      update();
      return $text.keyup(update);
    });

    return $('[data-render-markdown-label]').each((i, text) => {
      const $text = $(text);
      const $target = $text.next('[data-markdown-target]');
      return $target.html(markdown.render($text.data('render-markdown-label')));
    });
  }
};

export default SurveyAdmin;


text:
namespace blink {

class ExceptionState;

// CSSStyleVariableReferenceValue represents a CSS var() value for CSS Typed OM.
// The corresponding idl file is CSSVariableReferenceValue.idl.
class CORE_EXPORT CSSStyleVariableReferenceValue final
    : public ScriptWrappable {
  DEFINE_WRAPPERTYPEINFO();

 public:
  static CSSStyleVariableReferenceValue* Create(const String& variable,
                                                ExceptionState&);

  static CSSStyleVariableReferenceValue* Create(const String& variable,
                                                CSSUnparsedValue* fallback,
                                                ExceptionState&);

  static CSSStyleVariableReferenceValue* Create(
      const String& variable,
      CSSUnparsedValue* fallback = nullptr);

  CSSStyleVariableReferenceValue(const String& variable,
                                 CSSUnparsedValue* fallback)
      : variable_(variable), fallback_(fallback) {}

  const String& variable() const { return variable_; }
  void setVariable(const String&, ExceptionState&);

  CSSUnparsedValue* fallback() { return fallback_.Get(); }
  const CSSUnparsedValue* fallback() const { return fallback_.Get(); }

  void Trace(Visitor* visitor) override {
    visitor->Trace(fallback_);
    ScriptWrappable::Trace(visitor);
  }

 protected:
  String variable_;
  Member<CSSUnparsedValue> fallback_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CSSStyleVariableReferenceValue);
};

}  // namespace blink

#endif  // CSSStyleVariableReference_h


text:
import { CustomSurface } from 'substance'
import { NodeComponent } from '../../kit'

export default class AuthorsListComponent extends CustomSurface {
  getInitialState () {
    let items = this._getAuthors()
    return {
      hidden: items.length === 0,
      edit: false
    }
  }

  didMount () {
    super.didMount()

    const appState = this.context.editorState
    // FIXME: it is not good to rerender on every selection change.
    // Instead it should derive a state from the selection, and only rerender if the
    // state has changed (not-selected, selected + author id)
    appState.addObserver(['selection'], this.rerender, this, { stage: 'render' })
  }

  dispose () {
    super.dispose()
    this.context.editorState.removeObserver(this)
  }

  render ($$) {
    let el = $$('div').addClass('sc-authors-list')
    el.append(
      this._renderAuthors($$)
    )
    return el
  }

  _renderAuthors ($$) {
    const sel = this.context.editorState.selection
    const authors = this._getAuthors()
    let els = []
    authors.forEach((author, index) => {
      const authorEl = $$(AuthorDisplay, { node: author }).ref(author.id)
      if (sel && sel.nodeId === author.id) {
        authorEl.addClass('sm-selected')
      }
      els.push(authorEl)
      if (index < authors.length - 1) {
        els.push(', ')
      }
    })
    return els
  }

  _getCustomResourceId () {
    return 'authors-list'
  }

  _getAuthors () {
    return this.props.model.getItems()
  }
}

class AuthorDisplay extends NodeComponent {
  render ($$) {
    let el = $$('span').addClass('se-contrib').html(
      this.context.api.renderEntity(this.props.node)
    )
    el.on('mousedown', this._onMousedown)
      .on('click', this._onClick)
    return el
  }

  _onMousedown (e) {
    e.stopPropagation()
    if (e.button === 2) {
      this._select()
    }
  }

  _onClick (e) {
    e.stopPropagation()
    this._select()
  }

  _select () {
    this.context.api.selectEntity(this.props.node.id)
  }
}


text:
package net.codejava.spring.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import net.codejava.spring.dao.UserDAO;
import net.codejava.spring.dao.UserDAOImpl;
import net.codejava.spring.model.User;

@Configuration
@ComponentScan("net.codejava.spring")
@EnableTransactionManagement
public class ApplicationContextConfig {
	@Bean(name = "viewResolver")
	public InternalResourceViewResolver getViewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");
		return viewResolver;
	}

	@Bean(name = "dataSource")
	public DataSource getDataSource() {
		// BasicDataSource dataSource = new BasicDataSource();
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/usersdb");
		dataSource.setUsername("root");
		dataSource.setPassword("123456");
		return dataSource;
	}

	private Properties getHibernateProperties() {
		Properties properties = new Properties();
		properties.put("hibernate.show_sql", "true");
		properties.put("hibernate.dialect",
				"org.hibernate.dialect.MySQLDialect");
		return properties;
	}

	@Autowired
	@Bean(name = "sessionFactory")
	public SessionFactory getSessionFactory(DataSource dataSource) {
		LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(
				dataSource);
		sessionBuilder.addProperties(getHibernateProperties());
		sessionBuilder.addAnnotatedClasses(User.class);
		return sessionBuilder.buildSessionFactory();
	}

	@Autowired
	@Bean(name = "transactionManager")
	public HibernateTransactionManager getTransactionManager(
			SessionFactory sessionFactory) {
		HibernateTransactionManager transactionManager = new HibernateTransactionManager(
				sessionFactory);
		return transactionManager;
	}

	@Autowired
	@Bean(name = "userDao")
	public UserDAO getUserDao(SessionFactory sessionFactory) {
		return new UserDAOImpl(sessionFactory);
	}
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Sydowia 11: 102 (1958)

#### Original name
Meliola colae-simiarum Deighton

### Remarks
null


text:
<?php namespace Describe\Contracts;

/**
 * Interface IRunner
 * @package Describe\Contracts
 */
interface IRunner
{
    /**
     * Schedule test suite execution.
     *
     * @param ISuite $suite
     */
    public function schedule(ISuite $suite);

    /**
     * Execute test suites.
     */
    public function run();
}


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>TopCoder SRM 700 - 300: FindingFriend</title>

    <link type="image/x-icon" rel="shortcut icon" href="http://www.topcoder.com/i/favicon.ico"/>

        SRM 700
        1
        300
        FindingFriend

Problem Statement

            <intro escaped="1">

Your friend just took part in a popular online programming contest.
The participants were split across roomCount rooms, with each room containing exactly roomSize contestants.
We will use n = roomCount * roomSize to denote the total number of contestants.

The contest was such that there were no ties.
After the contest, each contestant had a distinct rank between 1 and n, inclusive.
(The contestant with rank 1 is the winner.)

A room winner is the contestant with the best (i.e., smallest) rank in their room.

You do not know the final standings.
The only thing you know are the ranks of all room winners.
More precisely, you are given a <type>int[]</type> leaders with roomCount elements.
The i-th element of leaders denotes the rank of the room winner of the i-th room.

Your friend just told you that her rank in this contest was friendPlace.

Return the number of different rooms in which your friend could have competed, given the information you have.

</intro>

Definition

                    Class
                    FindingFriend

                    Method
                    find

                    Parameters

                        int
                    ,
                        vector<int>
                    ,
                        int

                    Returns

                        int

                    Method signature

                        int find(int roomSize, vector<int> leaders, int friendPlace)

(be sure your method is public)

Limits

                    Time limit (s)
                    2.000

                    Memory limit (MB)
                    256

Notes

<note escaped="1">The value of n is not explicitly given in the arguments, but can be computed as roomSize times the number of elements in leaders.</note>

Constraints

<user-constraint escaped="1">roomSize will be between 1 and 1,000,000,000, inclusive.</user-constraint>

<user-constraint escaped="1">roomCount will be between 1 and 1,000, inclusive.</user-constraint>

<user-constraint escaped="1">Additionally, roomSize and roomCount will be such that n (that is, roomSize times roomCount) will not exceed 1,000,000,000.</user-constraint>

<user-constraint escaped="1">leaders will contain exactly roomCount elements.</user-constraint>

<user-constraint escaped="1">Each element of leaders will be between 1 and n, inclusive.</user-constraint>

<user-constraint escaped="1">All elements of leaders will be distinct.</user-constraint>

<user-constraint escaped="1">It is guaranteed there is at least one distribution of contestants into rooms that is consistent with leaders.</user-constraint>

<user-constraint escaped="1">friendPlace will be between 1 and n, inclusive.</user-constraint>

Test cases

input

                                roomSize

                                    2

                                leaders

                                    { 5, 1, 2 }

                                friendPlace

                                    4

output

                        Returns

                            2

note

We have 6 contestants: 3 rooms with 2 contestants in each of them.
Your friend finished 4-th.
Given the information you have, there are only two possible distributions of contestant ranks into rooms:

Room 1: ranks 5 and 6. Room 2: ranks 1 and 3. Room 3: ranks 2 and 4.

Room 1: ranks 5 and 6. Room 2: ranks 1 and 4. Room 3: ranks 2 and 3.

Your friend has competed either in room 2 or in room 3.
There are two possible rooms, so the correct return value is 2.

input

                                roomSize

                                    5

                                leaders

                                    { 1, 2, 3, 4, 5 }

                                friendPlace

                                    4

output

                        Returns

                            1

note

You know for sure your friend is in room 4, as she is its room winner.

input

                                roomSize

                                    6

                                leaders

                                    { 10, 5, 1, 4, 2, 20 }

                                friendPlace

                                    9

output

                        Returns

                            4

note

Your friend can be in either of the rooms 2, 3, 4, and 5.

input

                                roomSize

                                    1000000000

                                leaders

                                    { 1 }

                                friendPlace

                                    700700700

output

                        Returns

                            1

input

                                roomSize

                                    2

                                leaders

                                    { 3, 6, 8, 1, 2 }

                                friendPlace

                                    10

output

                        Returns

                            5

    This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.


text:
import { decodeSentence as decodeAPB, APBPacket } from "./codecs/APB";
import { decodeSentence as decodeBWC, BWCPacket } from "./codecs/BWC";
import { decodeSentence as decodeDBT, encodePacket as encodeDBT, DBTPacket } from "./codecs/DBT";
import { decodeSentence as decodeDTM, DTMPacket } from "./codecs/DTM";
import { decodeSentence as decodeGGA, encodePacket as encodeGGA, GGAPacket } from "./codecs/GGA";
import { decodeSentence as decodeGLL, encodePacket as encodeGLL, GLLPacket } from "./codecs/GLL";
import { decodeSentence as decodeGNS, encodePacket as encodeGNS, GNSPacket } from "./codecs/GNS";
import { decodeSentence as decodeGSA, GSAPacket } from "./codecs/GSA";
import { decodeSentence as decodeGST, GSTPacket } from "./codecs/GST";
import { decodeSentence as decodeGSV, GSVPacket } from "./codecs/GSV";
import { decodeSentence as decodeHDG, HDGPacket } from "./codecs/HDG";
import { decodeSentence as decodeHDM, encodePacket as encodeHDM, HDMPacket } from "./codecs/HDM";
import { decodeSentence as decodeHDT, encodePacket as encodeHDT, HDTPacket } from "./codecs/HDT";
import { decodeSentence as decodeMTK, encodePacket as encodeMTK, MTKPacket } from "./codecs/MTK";
import { decodeSentence as decodeMWV, encodePacket as encodeMWV, MWVPacket } from "./codecs/MWV";
import { decodeSentence as decodeRDID, RDIDPacket } from "./codecs/RDID";
import { decodeSentence as decodeRMC, RMCPacket } from "./codecs/RMC";
import { decodeSentence as decodeVHW, VHWPacket } from "./codecs/VHW";
import { decodeSentence as decodeVTG, encodePacket as encodeVTG, VTGPacket } from "./codecs/VTG";
import { decodeSentence as decodeZDA, ZDAPacket } from "./codecs/ZDA";

import { validNmeaChecksum } from "./helpers";

export type Packet = APBPacket | BWCPacket | DBTPacket | DTMPacket | GGAPacket | GLLPacket | GNSPacket | GSAPacket | GSTPacket | GSVPacket | HDGPacket | HDMPacket | HDTPacket | MTKPacket | MWVPacket | RDIDPacket | RMCPacket | VHWPacket | VTGPacket | ZDAPacket;
export { APBPacket, BWCPacket, DBTPacket, DTMPacket, GGAPacket, GLLPacket, GNSPacket, GSAPacket, GSTPacket, GSVPacket, HDGPacket, HDMPacket, HDTPacket, MTKPacket, MWVPacket, RDIDPacket, RMCPacket, VHWPacket, VTGPacket, ZDAPacket };

type Decoder = (parts: string[]) => Packet;

const decoders: { [sentenceId: string]: Decoder } = {
    APB: decodeAPB,
    BWC: decodeBWC,
    DBT: decodeDBT,
    DTM: decodeDTM,
    GGA: decodeGGA,
    GLL: decodeGLL,
    GNS: decodeGNS,
    GSA: decodeGSA,
    GST: decodeGST,
    GSV: decodeGSV,
    HDG: decodeHDG,
    HDM: decodeHDM,
    HDT: decodeHDT,
    MTK: decodeMTK,
    MWV: decodeMWV,
    RDID: decodeRDID,
    RMC: decodeRMC,
    VHW: decodeVHW,
    VTG: decodeVTG,
    ZDA: decodeZDA
};

type Encoder = (packet: Packet, talker: string) => string;

const encoders: { [sentenceId: string]: Encoder } = {
    DBT: encodeDBT as Encoder,
    GGA: encodeGGA as Encoder,
    GLL: encodeGLL as Encoder,
    GNS: encodeGNS as Encoder,
    HDM: encodeHDM as Encoder,
    HDT: encodeHDT as Encoder,
    MTK: encodeMTK as Encoder,
    MWV: encodeMWV as Encoder,
    VTG: encodeVTG as Encoder
};

export function parseNmeaSentence(sentence: string): Packet {
    if (!validNmeaChecksum(sentence)) {
        throw Error(`Invalid sentence: "${sentence}".`);
    }

    const fields = sentence.split("*")[0].split(",");

    let talkerId: string;
    let sentenceId: string;
    if (fields[0].charAt(1) === "P") {
        talkerId = "P"; // Proprietary
        sentenceId = fields[0].substr(2);
    } else {
        talkerId = fields[0].substr(1, 2);
        sentenceId = fields[0].substr(3);
    }
    fields[0] = sentenceId;

    let parser = decoders[sentenceId];
    if (!parser && sentenceId.substr(0, 3) === "MTK") {
        parser = decodeMTK;
    }

    if (!parser) {
        throw Error(`No known parser for sentence ID "${sentenceId}".`);
    }

    const packet = parser(fields);
    packet.talkerId = talkerId;
    return packet;
}

export function encodeNmeaPacket(packet: Packet, talker: string = "P"): string {
    if (packet === undefined) {
        throw new Error("Packet must be given.");
    }

    const encoder = encoders[packet.sentenceId];
    if (encoder) {
        return encoder(packet, talker);
    } else {
        throw Error(`No known encoder for sentence ID "${packet.sentenceId}"`);
    }
}


text:
#include "graphicalModel.h"

#include <QtCore/QUuid>

#include "models/details/logicalModel.h"

using namespace qReal;
using namespace models;
using namespace models::details;
using namespace modelsImplementation;

GraphicalModel::GraphicalModel(qrRepo::GraphicalRepoApi *repoApi
		, const EditorManagerInterface &editorManagerInterface
		)
	: AbstractModel(editorManagerInterface)
	, mLogicalModelView(this)
	, mApi(*repoApi)
	, mGraphicalAssistApi(nullptr)
{
	mRootItem = new GraphicalModelItem(Id::rootId(), Id(), nullptr);
	init();
}

GraphicalModel::~GraphicalModel()
{
	delete mGraphicalAssistApi;
	cleanupTree(mRootItem);
}

void GraphicalModel::setAssistApi(GraphicalModelAssistApi * const graphicalAssistApi)
{
	mGraphicalAssistApi = graphicalAssistApi;
}

void GraphicalModel::init()
{
	mModelItems.insert(Id::rootId(), mRootItem);
	mApi.setName(Id::rootId(), Id::rootId().toString());
	// Turn off view notification while loading. Model can be inconsistent during a process,
	// so views shall not update themselves before time. It is important for
	// scene, where adding edge before adding nodes may lead to disconnected edge.	blockSignals(true);
	blockSignals(true);
	loadSubtreeFromClient(static_cast<GraphicalModelItem *>(mRootItem));
	blockSignals(false);
}

void GraphicalModel::loadSubtreeFromClient(GraphicalModelItem * const parent)
{
	/// @todo There must be a way to tell nodes from edges in repository, or we need to implement correct loading
	/// at higher level. For now we check the existence of "from" property, which is bad, because a node can also
	/// have this property.
	/// Nodes need to be loaded before adges due to bugs in scene which connects edges to incorrect nodes or does
	/// not connect edges at all. Proper fix for that shall possibly be in scene instead of this place.
	foreach (const Id &childId, mApi.children(parent->id())) {
		if (mApi.isGraphicalElement(childId) && !mApi.hasProperty(childId, "from")) {
			GraphicalModelItem * const child = loadElement(parent, childId);
			loadSubtreeFromClient(child);
		}
	}

	foreach (const Id &childId, mApi.children(parent->id())) {
		if (mApi.isGraphicalElement(childId) && mApi.hasProperty(childId, "from")) {
			GraphicalModelItem * const child = loadElement(parent, childId);
			loadSubtreeFromClient(child);
		}
	}
}

GraphicalModelItem *GraphicalModel::loadElement(GraphicalModelItem *parentItem, const Id &id)
{
	int newRow = parentItem->children().size();

	beginInsertRows(index(parentItem), newRow, newRow);
	const Id logicalId = mApi.logicalId(id);
	GraphicalModelItem *item = new GraphicalModelItem(id, logicalId, parentItem);
	parentItem->addChild(item);
	mModelItems.insert(id, item);
	endInsertRows();

	return item;
}

void GraphicalModel::connectToLogicalModel(LogicalModel * const logicalModel)
{
	mLogicalModelView.setModel(logicalModel);
}

AbstractModelItem *GraphicalModel::createModelItem(const Id &id, AbstractModelItem *parentItem) const
{
	return new GraphicalModelItem(id, Id(id.type(), QUuid::createUuid().toString())
								  , static_cast<GraphicalModelItem *>(parentItem));
}

void GraphicalModel::updateElements(const Id &logicalId, const QString &name)
{
	foreach (AbstractModelItem *item,  mModelItems.values()) {
		GraphicalModelItem *graphicalItem = static_cast<GraphicalModelItem *>(item);
		if (graphicalItem->logicalId() == logicalId) {
			setNewName(graphicalItem->id(), name);
			emit dataChanged(index(graphicalItem), index(graphicalItem));
		}
	}
}

void GraphicalModel::addElementToModel(const Id &parent, const Id &id
		, const Id &logicalId, const QString &name, const QPointF &position)
{
	Q_ASSERT_X(mModelItems.contains(parent), "addElementToModel", "Adding element to non-existing parent");
	AbstractModelItem *parentItem = mModelItems[parent];

	GraphicalModelItem *newGraphicalModelItem = nullptr;
	Id actualLogicalId = logicalId;
	if (logicalId == Id::rootId() || logicalId.isNull()) {
		AbstractModelItem *newItem = createModelItem(id, parentItem);
		newGraphicalModelItem = static_cast<GraphicalModelItem *>(newItem);
		actualLogicalId = newGraphicalModelItem->logicalId();
	} else {
		GraphicalModelItem *graphicalParentItem = static_cast<GraphicalModelItem *>(parentItem);
		newGraphicalModelItem = new GraphicalModelItem(id, logicalId, graphicalParentItem);
	}

	initializeElement(id, actualLogicalId, parentItem, newGraphicalModelItem, name, position);
	emit elementAdded(id);
}

void GraphicalModel::initializeElement(const Id &id, const Id &logicalId
		, modelsImplementation::AbstractModelItem *parentItem, modelsImplementation::AbstractModelItem *item
		, const QString &name, const QPointF &position)
{
	const int newRow = parentItem->children().size();

	beginInsertRows(index(parentItem), newRow, newRow);
	parentItem->addChild(item);
	mApi.addChild(parentItem->id(), id, logicalId);
	mApi.setName(id, name);
	mApi.setFromPort(id, 0.0);
	mApi.setToPort(id, 0.0);
	mApi.setFrom(id, Id::rootId());
	mApi.setTo(id, Id::rootId());
	mApi.setProperty(id, "links", IdListHelper::toVariant(IdList()));
	mApi.setPosition(id, position);
	mApi.setConfiguration(id, QVariant(QPolygon()));
	mModelItems.insert(id, item);
	endInsertRows();
}

QVariant GraphicalModel::data(const QModelIndex &index, int role) const
{
	if (index.isValid()) {
		GraphicalModelItem *item = static_cast<GraphicalModelItem*>(index.internalPointer());
		Q_ASSERT(item);
		switch (role) {
		case Qt::DisplayRole:
		case Qt::EditRole:
			return mApi.name(item->id());
		case Qt::DecorationRole:
			return mEditorManagerInterface.icon(item->id());
		case roles::idRole:
			return item->id().toVariant();
		case roles::logicalIdRole:
			return item->logicalId().toVariant();
		case roles::positionRole:
			return mApi.position(item->id());
		case roles::fromRole:
			return mApi.from(item->id()).toVariant();
		case roles::toRole:
			return mApi.to(item->id()).toVariant();
		case roles::fromPortRole:
			return mApi.fromPort(item->id());
		case roles::toPortRole:
			return mApi.toPort(item->id());
		case roles::configurationRole:
			return mApi.configuration(item->id());
		}
		if (role >= roles::customPropertiesBeginRole) {
			return QVariant();  // Custom properties are invalid for graphical objects for now.
		}
		Q_ASSERT(role < Qt::UserRole);
		return QVariant();
	} else {
		return QVariant();
	}
}

bool GraphicalModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	if (index.isValid()) {
		AbstractModelItem *item = static_cast<AbstractModelItem *>(index.internalPointer());
		switch (role) {
		case Qt::DisplayRole:
		case Qt::EditRole:
			setNewName(item->id(), value.toString());
			break;
		case roles::positionRole:
			mApi.setPosition(item->id(), value);
			break;
		case roles::configurationRole:
			mApi.setConfiguration(item->id(), value);
			break;
		case roles::fromRole:
			mApi.setFrom(item->id(), value.value<Id>());
			break;
		case roles::toRole:
			mApi.setTo(item->id(), value.value<Id>());
			break;
		case roles::fromPortRole:
			mApi.setFromPort(item->id(), value.toDouble());
			break;
		case roles::toPortRole:
			mApi.setToPort(item->id(), value.toDouble());
			break;
		default:
			if (role >= roles::customPropertiesBeginRole) {
				QString selectedProperty = findPropertyName(item->id(), role);
				mApi.setProperty(item->id(), selectedProperty, value);
				break;
			}
			Q_ASSERT(role < Qt::UserRole);
			return false;
		}
		emit dataChanged(index, index);
		return true;
	}
	return false;
}

void GraphicalModel::setNewName(const Id &id, const QString newValue)
{
	mApi.setName(id, newValue);
	emit nameChanged(id);
}

void GraphicalModel::changeParent(const QModelIndex &element, const QModelIndex &parent, const QPointF &position)
{
	if (!parent.isValid() || element.parent() == parent) {
		return;
	}

	int destinationRow = parentAbstractItem(parent)->children().size();

	if (beginMoveRows(element.parent(), element.row(), element.row(), parent, destinationRow)) {
		AbstractModelItem *elementItem = static_cast<AbstractModelItem*>(element.internalPointer());
		QVariant configuration = mApi.configuration(elementItem->id());
		elementItem->parent()->removeChild(elementItem);
		AbstractModelItem *parentItem = parentAbstractItem(parent);

		mApi.setParent(elementItem->id(), parentItem->id());

		elementItem->setParent(parentItem);

		parentItem->addChild(elementItem);

		mApi.setPosition(elementItem->id(), position);
		mApi.setConfiguration(elementItem->id(), configuration);
		endMoveRows();

		if (parent.row() != element.row()) {
			emit dataChanged(parent, element);
		}
	}
}

void GraphicalModel::stackBefore(const QModelIndex &element, const QModelIndex &sibling)
{
	if (element == sibling) {
		return;
	}

	if (beginMoveRows(element.parent(), element.row(), element.row(), element.parent(), sibling.row())) {
		AbstractModelItem *parent = static_cast<AbstractModelItem *>(element.parent().internalPointer());
		AbstractModelItem *item = static_cast<AbstractModelItem *>(element.internalPointer());
		AbstractModelItem *siblingItem = static_cast<AbstractModelItem *>(sibling.internalPointer());

		parent->stackBefore(item, siblingItem);
		mApi.stackBefore(parent->id(), item->id(), siblingItem->id());
		endMoveRows();
	} else {
		qDebug() << "GraphicalModel::stackBefore : problem with beginMoveRows";
	}
}

const qrRepo::GraphicalRepoApi &GraphicalModel::api() const
{
	return mApi;
}

qrRepo::GraphicalRepoApi &GraphicalModel::mutableApi() const
{
	return mApi;
}

GraphicalModelAssistApi &GraphicalModel::graphicalModelAssistApi() const
{
	return *mGraphicalAssistApi;
}

bool GraphicalModel::removeRows(int row, int count, const QModelIndex &parent)
{
	AbstractModelItem *parentItem = parentAbstractItem(parent);
	if (parentItem->children().size() < row + count) {
		return false;
	} else {
		for (int i = row; i < row + count; ++i) {
			AbstractModelItem *child = parentItem->children().at(i);
			removeModelItems(child);

			int childRow = child->row();
			beginRemoveRows(parent, childRow, childRow);
			child->parent()->removeChild(child);
			mModelItems.remove(child->id());
			mApi.removeChild(parentItem->id(), child->id());
			mApi.removeElement(child->id());
			delete child;
			endRemoveRows();
		}
		return true;
	}
}

void GraphicalModel::removeModelItemFromApi(details::modelsImplementation::AbstractModelItem *const root
		, details::modelsImplementation::AbstractModelItem *child)
{
	mApi.removeProperty(child->id(), "position");
	mApi.removeProperty(child->id(), "configuration");
	if (mModelItems.count(child->id()) == 0) {
		mApi.removeChild(root->id(),child->id());
	}
	mApi.removeElement(child->id());
}

QList<QPersistentModelIndex> GraphicalModel::indexesWithLogicalId(const Id &logicalId) const
{
	QList<QPersistentModelIndex> indexes;
	foreach (AbstractModelItem *item, mModelItems.values()) {
		if (static_cast<GraphicalModelItem *>(item)->logicalId() == logicalId)
			indexes.append(index(item));
	}
	return indexes;
}

qReal::details::ModelsAssistInterface* GraphicalModel::modelAssistInterface() const
{
	return mGraphicalAssistApi;
}


text:
/* global describe, it, require */
'use strict';

// MODULES //

var // Expectation library:
	chai = require( 'chai' ),

	// Deep close to:
	deepCloseTo = require( './utils/deepcloseto.js' ),

	// Module to be tested:
	zscore = require( './../lib/array.js' );

// VARIABLES //

var expect = chai.expect,
	assert = chai.assert;

// TESTS //

describe( 'typed-array zscore', function tests() {

	it( 'should export a function', function test() {
		expect( zscore ).to.be.a( 'function' );
	});

	it( 'should standardize elements', function test() {
		var data, actual, expected;

		data = new Float64Array( [
			10,
			20,
			40,
			30,
			40,
			50,
			60,
			70
		] );
		actual = new Float64Array( data.length );

		actual = zscore( actual, data );
		expected = {
			'zscores': new Float32Array( [ -1.5, -1, 0, -0.5, 0, 0.5, 1, 1.5 ] ),
			'mu': 40,
			'sigma': 20
		};

		assert.deepEqual( actual, expected );
	});

	it( 'should return an empty array if provided an empty array', function test() {
		assert.deepEqual( zscore( new Int8Array(), new Int8Array() ), { 'zscores': new Int8Array(), 'mu': null, 'sigma': null } );
	});

});