/**
 * HTML elements and other resources for web-based applications that need to
 * interact with the browser and the DOM (Document Object Model).
 *
 * This library includes DOM element types, CSS styling, local storage,
 * media, speech, events, and more.
 * To get started,
 * check out the [Element] class, the base class for many of the HTML
 * DOM types.
 *
 * For information on writing web apps with Dart, see https://webdev.dartlang.org.
 *
 * {@category Web}
 */
library dart.dom.html;

import 'dart:async';
import 'dart:collection' hide LinkedList, LinkedListEntry;
import 'dart:_internal' hide Symbol;
import 'dart:html_common';
import 'dart:indexed_db';
import "dart:convert";
import 'dart:math';
import 'dart:_native_typed_data';
import 'dart:typed_data';
import 'dart:svg' as svg;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList;
import 'dart:web_gl' as gl;
import 'dart:web_gl' show RenderingContext, RenderingContext2;
import 'dart:web_sql';
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// DO NOT EDIT - unless you are editing documentation as per:
// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
// Auto-generated dart:html library.

// Not actually used, but imported since dart:html can generate these objects.
import 'dart:_js_helper'
    show
        convertDartClosureToJS,
        Creates,
        JavaScriptIndexingBehavior,
        JSName,
        Native,
        Returns,
        ForceInline,
        findDispatchTagForInterceptorClass,
        setNativeSubclassDispatchRecord,
        makeLeafDispatchRecord,
        registerGlobalObject,
        applyExtension;
import 'dart:_interceptors'
    show
        Interceptor,
        JavaScriptFunction,
        JSExtendableArray,
        JSUInt31,
        findInterceptorConstructorForType,
        findConstructorForNativeSubclassType,
        getNativeInterceptor,
        setDispatchProperty;

export 'dart:math' show Rectangle, Point;
export 'dart:_internal' show HttpStatus;

/**
 * Top-level container for a web page, which is usually a browser tab or window.
 *
 * Each web page loaded in the browser has its own [Window], which is a
 * container for the web page.
 *
 * If the web page has any `<iframe>` elements, then each `<iframe>` has its own
 * [Window] object, which is accessible only to that `<iframe>`.
 *
 * See also:
 *
 *   * [Window](https://developer.mozilla.org/en-US/docs/Web/API/window) from MDN.
 */
Window get window => JS('Window', 'window');

/**
 * Root node for all content in a web page.
 */
HtmlDocument get document =>
    JS('returns:HtmlDocument;depends:none;effects:none;gvn:true', 'document');

// Supoort to convert JS Promise to a Dart Future.
Future<T> promiseToFuture<T>(jsPromise) {
  var completer = new Completer<T>();

  var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
  var thenErrorCode = (promiseError) => completer.completeError(promiseError);

  JS("", "#.then(#, #)", jsPromise, convertDartClosureToJS(thenSuccessCode, 1),
      convertDartClosureToJS(thenErrorCode, 1));

  return completer.future;
}

// Supoort to convert JS Promise to a Dart Future<Map<String, dynamic>>.  Each property of the JS
// object is added to the Map as a key of type String with a value of type dynamic.
Future<Map<String, dynamic>> promiseToFutureAsMap(jsPromise) {
  var completer = new Completer<Map<String, dynamic>>();

  var thenSuccessCode = (promiseValue) =>
      completer.complete(convertNativeToDart_Dictionary(promiseValue));
  var thenErrorCode = (promiseError) => completer.completeError(promiseError);

  JS("", "#.then(#, #)", jsPromise, convertDartClosureToJS(thenSuccessCode, 1),
      convertDartClosureToJS(thenErrorCode, 1));

  return completer.future;
}

// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
@Native("HTMLElement")
class HtmlElement extends Element implements NoncedElement {
  factory HtmlElement() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlElement.created() : super.created();

  // From NoncedElement
  String nonce;
}

/**
 * Emitted for any setlike IDL entry needs a callback signature.
 * Today there is only one.
 */
typedef void FontFaceSetForEachCallback(
    FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);

WorkerGlobalScope get _workerSelf => JS('WorkerGlobalScope', 'self');
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AbortPaymentEvent")
class AbortPaymentEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory AbortPaymentEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory AbortPaymentEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return AbortPaymentEvent._create_1(type, eventInitDict_1);
  }
  static AbortPaymentEvent _create_1(type, eventInitDict) => JS(
      'AbortPaymentEvent', 'new AbortPaymentEvent(#,#)', type, eventInitDict);

  void respondWith(Future paymentAbortedResponse) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AbsoluteOrientationSensor")
class AbsoluteOrientationSensor extends OrientationSensor {
  // To suppress missing implicit constructor warnings.
  factory AbsoluteOrientationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory AbsoluteOrientationSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return AbsoluteOrientationSensor._create_1(sensorOptions_1);
    }
    return AbsoluteOrientationSensor._create_2();
  }
  static AbsoluteOrientationSensor _create_1(sensorOptions) => JS(
      'AbsoluteOrientationSensor',
      'new AbsoluteOrientationSensor(#)',
      sensorOptions);
  static AbsoluteOrientationSensor _create_2() =>
      JS('AbsoluteOrientationSensor', 'new AbsoluteOrientationSensor()');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class AbstractWorker extends Interceptor implements EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AbstractWorker._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [AbstractWorker].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /// Stream of `error` events handled by this [AbstractWorker].
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Accelerometer")
class Accelerometer extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory Accelerometer._() {
    throw new UnsupportedError("Not supported");
  }

  factory Accelerometer([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return Accelerometer._create_1(sensorOptions_1);
    }
    return Accelerometer._create_2();
  }
  static Accelerometer _create_1(sensorOptions) =>
      JS('Accelerometer', 'new Accelerometer(#)', sensorOptions);
  static Accelerometer _create_2() =>
      JS('Accelerometer', 'new Accelerometer()');

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AccessibleNode")
class AccessibleNode extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AccessibleNode._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> accessibleClickEvent =
      const EventStreamProvider<Event>('accessibleclick');

  static const EventStreamProvider<Event> accessibleContextMenuEvent =
      const EventStreamProvider<Event>('accessiblecontextmenu');

  static const EventStreamProvider<Event> accessibleDecrementEvent =
      const EventStreamProvider<Event>('accessibledecrement');

  static const EventStreamProvider<Event> accessibleFocusEvent =
      const EventStreamProvider<Event>('accessiblefocus');

  static const EventStreamProvider<Event> accessibleIncrementEvent =
      const EventStreamProvider<Event>('accessibleincrement');

  static const EventStreamProvider<Event> accessibleScrollIntoViewEvent =
      const EventStreamProvider<Event>('accessiblescrollintoview');

  factory AccessibleNode() {
    return AccessibleNode._create_1();
  }
  static AccessibleNode _create_1() =>
      JS('AccessibleNode', 'new AccessibleNode()');

  AccessibleNode activeDescendant;

  bool atomic;

  String autocomplete;

  bool busy;

  String checked;

  int colCount;

  int colIndex;

  int colSpan;

  AccessibleNodeList controls;

  String current;

  AccessibleNodeList describedBy;

  AccessibleNode details;

  bool disabled;

  AccessibleNode errorMessage;

  bool expanded;

  AccessibleNodeList flowTo;

  String hasPopUp;

  bool hidden;

  String invalid;

  String keyShortcuts;

  String label;

  AccessibleNodeList labeledBy;

  int level;

  String live;

  bool modal;

  bool multiline;

  bool multiselectable;

  String orientation;

  AccessibleNodeList owns;

  String placeholder;

  int posInSet;

  String pressed;

  bool readOnly;

  String relevant;

  bool required;

  String role;

  String roleDescription;

  int rowCount;

  int rowIndex;

  int rowSpan;

  bool selected;

  int setSize;

  String sort;

  num valueMax;

  num valueMin;

  num valueNow;

  String valueText;

  void appendChild(AccessibleNode child) native;

  Stream<Event> get onAccessibleClick => accessibleClickEvent.forTarget(this);

  Stream<Event> get onAccessibleContextMenu =>
      accessibleContextMenuEvent.forTarget(this);

  Stream<Event> get onAccessibleDecrement =>
      accessibleDecrementEvent.forTarget(this);

  Stream<Event> get onAccessibleFocus => accessibleFocusEvent.forTarget(this);

  Stream<Event> get onAccessibleIncrement =>
      accessibleIncrementEvent.forTarget(this);

  Stream<Event> get onAccessibleScrollIntoView =>
      accessibleScrollIntoViewEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AccessibleNodeList")
class AccessibleNodeList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AccessibleNodeList._() {
    throw new UnsupportedError("Not supported");
  }

  factory AccessibleNodeList([List<AccessibleNode> nodes]) {
    if (nodes != null) {
      return AccessibleNodeList._create_1(nodes);
    }
    return AccessibleNodeList._create_2();
  }
  static AccessibleNodeList _create_1(nodes) =>
      JS('AccessibleNodeList', 'new AccessibleNodeList(#)', nodes);
  static AccessibleNodeList _create_2() =>
      JS('AccessibleNodeList', 'new AccessibleNodeList()');

  int length;

  void __setter__(int index, AccessibleNode node) native;

  void add(AccessibleNode node, AccessibleNode before) native;

  AccessibleNode item(int index) native;

  void remove(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AmbientLightSensor")
class AmbientLightSensor extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory AmbientLightSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory AmbientLightSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return AmbientLightSensor._create_1(sensorOptions_1);
    }
    return AmbientLightSensor._create_2();
  }
  static AmbientLightSensor _create_1(sensorOptions) =>
      JS('AmbientLightSensor', 'new AmbientLightSensor(#)', sensorOptions);
  static AmbientLightSensor _create_2() =>
      JS('AmbientLightSensor', 'new AmbientLightSensor()');

  final num illuminance;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLAnchorElement")
class AnchorElement extends HtmlElement implements HtmlHyperlinkElementUtils {
  // To suppress missing implicit constructor warnings.
  factory AnchorElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory AnchorElement({String href}) {
    AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true',
        '#.createElement(#)', document, "a");
    if (href != null) e.href = href;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AnchorElement.created() : super.created();

  String download;

  String hreflang;

  String referrerPolicy;

  String rel;

  String target;

  String type;

  // From HTMLHyperlinkElementUtils

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Animation")
class Animation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Animation._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> cancelEvent =
      const EventStreamProvider<Event>('cancel');

  static const EventStreamProvider<Event> finishEvent =
      const EventStreamProvider<Event>('finish');

  factory Animation(
      [AnimationEffectReadOnly effect, AnimationTimeline timeline]) {
    if (timeline != null) {
      return Animation._create_1(effect, timeline);
    }
    if (effect != null) {
      return Animation._create_2(effect);
    }
    return Animation._create_3();
  }
  static Animation _create_1(effect, timeline) =>
      JS('Animation', 'new Animation(#,#)', effect, timeline);
  static Animation _create_2(effect) =>
      JS('Animation', 'new Animation(#)', effect);
  static Animation _create_3() => JS('Animation', 'new Animation()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(document.body.animate)');

  num currentTime;

  AnimationEffectReadOnly effect;

  Future<Animation> get finished =>
      promiseToFuture<Animation>(JS("", "#.finished", this));

  String id;

  final String playState;

  num playbackRate;

  Future<Animation> get ready =>
      promiseToFuture<Animation>(JS("", "#.ready", this));

  num startTime;

  final AnimationTimeline timeline;

  void cancel() native;

  void finish() native;

  void pause() native;

  void play() native;

  void reverse() native;

  Stream<Event> get onCancel => cancelEvent.forTarget(this);

  Stream<Event> get onFinish => finishEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEffectReadOnly")
class AnimationEffectReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final AnimationEffectTimingReadOnly timing;

  Map getComputedTiming() {
    return convertNativeToDart_Dictionary(_getComputedTiming_1());
  }

  @JSName('getComputedTiming')
  _getComputedTiming_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEffectTiming")
class AnimationEffectTiming extends AnimationEffectTimingReadOnly {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectTiming._() {
    throw new UnsupportedError("Not supported");
  }

  // Shadowing definition.
  num get delay => JS("num", "#.delay", this);

  set delay(num value) {
    JS("void", "#.delay = #", this, value);
  }

  // Shadowing definition.
  String get direction => JS("String", "#.direction", this);

  set direction(String value) {
    JS("void", "#.direction = #", this, value);
  }

  // Shadowing definition.
  Object get duration => JS("Object", "#.duration", this);

  set duration(Object value) {
    JS("void", "#.duration = #", this, value);
  }

  // Shadowing definition.
  String get easing => JS("String", "#.easing", this);

  set easing(String value) {
    JS("void", "#.easing = #", this, value);
  }

  // Shadowing definition.
  num get endDelay => JS("num", "#.endDelay", this);

  set endDelay(num value) {
    JS("void", "#.endDelay = #", this, value);
  }

  // Shadowing definition.
  String get fill => JS("String", "#.fill", this);

  set fill(String value) {
    JS("void", "#.fill = #", this, value);
  }

  // Shadowing definition.
  num get iterationStart => JS("num", "#.iterationStart", this);

  set iterationStart(num value) {
    JS("void", "#.iterationStart = #", this, value);
  }

  // Shadowing definition.
  num get iterations => JS("num", "#.iterations", this);

  set iterations(num value) {
    JS("void", "#.iterations = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEffectTimingReadOnly")
class AnimationEffectTimingReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectTimingReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final num delay;

  final String direction;

  final Object duration;

  final String easing;

  final num endDelay;

  final String fill;

  final num iterationStart;

  final num iterations;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEvent")
class AnimationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory AnimationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AnimationEvent._create_1(type, eventInitDict_1);
    }
    return AnimationEvent._create_2(type);
  }
  static AnimationEvent _create_1(type, eventInitDict) =>
      JS('AnimationEvent', 'new AnimationEvent(#,#)', type, eventInitDict);
  static AnimationEvent _create_2(type) =>
      JS('AnimationEvent', 'new AnimationEvent(#)', type);

  final String animationName;

  final num elapsedTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationPlaybackEvent")
class AnimationPlaybackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationPlaybackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory AnimationPlaybackEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AnimationPlaybackEvent._create_1(type, eventInitDict_1);
    }
    return AnimationPlaybackEvent._create_2(type);
  }
  static AnimationPlaybackEvent _create_1(type, eventInitDict) => JS(
      'AnimationPlaybackEvent',
      'new AnimationPlaybackEvent(#,#)',
      type,
      eventInitDict);
  static AnimationPlaybackEvent _create_2(type) =>
      JS('AnimationPlaybackEvent', 'new AnimationPlaybackEvent(#)', type);

  final num currentTime;

  final num timelineTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationTimeline")
class AnimationTimeline extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  final num currentTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationWorkletGlobalScope")
class AnimationWorkletGlobalScope extends WorkletGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory AnimationWorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  void registerAnimator(String name, Object animatorConstructor) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * ApplicationCache is accessed via [Window.applicationCache].
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.OPERA)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("ApplicationCache,DOMApplicationCache,OfflineResourceList")
class ApplicationCache extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ApplicationCache._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `cached` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> cachedEvent =
      const EventStreamProvider<Event>('cached');

  /**
   * Static factory designed to expose `checking` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> checkingEvent =
      const EventStreamProvider<Event>('checking');

  /**
   * Static factory designed to expose `downloading` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> downloadingEvent =
      const EventStreamProvider<Event>('downloading');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `noupdate` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> noUpdateEvent =
      const EventStreamProvider<Event>('noupdate');

  /**
   * Static factory designed to expose `obsolete` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> obsoleteEvent =
      const EventStreamProvider<Event>('obsolete');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `updateready` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> updateReadyEvent =
      const EventStreamProvider<Event>('updateready');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.applicationCache)');

  static const int CHECKING = 2;

  static const int DOWNLOADING = 3;

  static const int IDLE = 1;

  static const int OBSOLETE = 5;

  static const int UNCACHED = 0;

  static const int UPDATEREADY = 4;

  final int status;

  void abort() native;

  void swapCache() native;

  void update() native;

  /// Stream of `cached` events handled by this [ApplicationCache].
  Stream<Event> get onCached => cachedEvent.forTarget(this);

  /// Stream of `checking` events handled by this [ApplicationCache].
  Stream<Event> get onChecking => checkingEvent.forTarget(this);

  /// Stream of `downloading` events handled by this [ApplicationCache].
  Stream<Event> get onDownloading => downloadingEvent.forTarget(this);

  /// Stream of `error` events handled by this [ApplicationCache].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `noupdate` events handled by this [ApplicationCache].
  Stream<Event> get onNoUpdate => noUpdateEvent.forTarget(this);

  /// Stream of `obsolete` events handled by this [ApplicationCache].
  Stream<Event> get onObsolete => obsoleteEvent.forTarget(this);

  /// Stream of `progress` events handled by this [ApplicationCache].
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `updateready` events handled by this [ApplicationCache].
  Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ApplicationCacheErrorEvent")
class ApplicationCacheErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ApplicationCacheErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ApplicationCacheErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ApplicationCacheErrorEvent._create_1(type, eventInitDict_1);
    }
    return ApplicationCacheErrorEvent._create_2(type);
  }
  static ApplicationCacheErrorEvent _create_1(type, eventInitDict) => JS(
      'ApplicationCacheErrorEvent',
      'new ApplicationCacheErrorEvent(#,#)',
      type,
      eventInitDict);
  static ApplicationCacheErrorEvent _create_2(type) => JS(
      'ApplicationCacheErrorEvent', 'new ApplicationCacheErrorEvent(#)', type);

  final String message;

  final String reason;

  final int status;

  final String url;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * DOM Area Element, which links regions of an image map with a hyperlink.
 *
 * The element can also define an uninteractive region of the map.
 *
 * See also:
 *
 * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
 * on MDN.
 */
@Native("HTMLAreaElement")
class AreaElement extends HtmlElement implements HtmlHyperlinkElementUtils {
  // To suppress missing implicit constructor warnings.
  factory AreaElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory AreaElement() => JS(
      'returns:AreaElement;creates:AreaElement;new:true',
      '#.createElement(#)',
      document,
      "area");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AreaElement.created() : super.created();

  String alt;

  String coords;

  String download;

  String referrerPolicy;

  String rel;

  String shape;

  String target;

  // From HTMLHyperlinkElementUtils

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLAudioElement")
class AudioElement extends MediaElement {
  factory AudioElement._([String src]) {
    if (src != null) {
      return AudioElement._create_1(src);
    }
    return AudioElement._create_2();
  }
  static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
  static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AudioElement.created() : super.created();

  factory AudioElement([String src]) => new AudioElement._(src);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AuthenticatorAssertionResponse")
class AuthenticatorAssertionResponse extends AuthenticatorResponse {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorAssertionResponse._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer authenticatorData;

  final ByteBuffer signature;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AuthenticatorAttestationResponse")
class AuthenticatorAttestationResponse extends AuthenticatorResponse {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorAttestationResponse._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer attestationObject;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AuthenticatorResponse")
class AuthenticatorResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorResponse._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('clientDataJSON')
  final ByteBuffer clientDataJson;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLBRElement")
class BRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory BRElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory BRElement() => JS('returns:BRElement;creates:BRElement;new:true',
      '#.createElement(#)', document, "br");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BRElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchClickEvent")
class BackgroundFetchClickEvent extends BackgroundFetchEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchClickEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchClickEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchClickEvent._create_1(type, init_1);
  }
  static BackgroundFetchClickEvent _create_1(type, init) => JS(
      'BackgroundFetchClickEvent',
      'new BackgroundFetchClickEvent(#,#)',
      type,
      init);

  final String state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchEvent")
class BackgroundFetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchEvent._create_1(type, init_1);
  }
  static BackgroundFetchEvent _create_1(type, init) =>
      JS('BackgroundFetchEvent', 'new BackgroundFetchEvent(#,#)', type, init);

  final String id;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchFailEvent")
class BackgroundFetchFailEvent extends BackgroundFetchEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchFailEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchFailEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchFailEvent._create_1(type, init_1);
  }
  static BackgroundFetchFailEvent _create_1(type, init) => JS(
      'BackgroundFetchFailEvent',
      'new BackgroundFetchFailEvent(#,#)',
      type,
      init);

  final List<BackgroundFetchSettledFetch> fetches;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchFetch")
class BackgroundFetchFetch extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchFetch._() {
    throw new UnsupportedError("Not supported");
  }

  final _Request request;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchManager")
class BackgroundFetchManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<BackgroundFetchRegistration> fetch(String id, Object requests,
      [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<BackgroundFetchRegistration>(
        JS("", "#.fetch(#, #, #)", this, id, requests, options_dict));
  }

  Future<BackgroundFetchRegistration> get(String id) =>
      promiseToFuture<BackgroundFetchRegistration>(
          JS("", "#.get(#)", this, id));

  Future<List<String>> getIds() =>
      promiseToFuture<List<String>>(JS("", "#.getIds()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchRegistration")
class BackgroundFetchRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchRegistration._() {
    throw new UnsupportedError("Not supported");
  }

  final int downloadTotal;

  final int downloaded;

  final String id;

  final String title;

  final int totalDownloadSize;

  final int uploadTotal;

  final int uploaded;

  Future<bool> abort() => promiseToFuture<bool>(JS("", "#.abort()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchSettledFetch")
class BackgroundFetchSettledFetch extends BackgroundFetchFetch {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchSettledFetch._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchSettledFetch(_Request request, _Response response) {
    return BackgroundFetchSettledFetch._create_1(request, response);
  }
  static BackgroundFetchSettledFetch _create_1(request, response) => JS(
      'BackgroundFetchSettledFetch',
      'new BackgroundFetchSettledFetch(#,#)',
      request,
      response);

  final _Response response;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchedEvent")
class BackgroundFetchedEvent extends BackgroundFetchEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchedEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchedEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchedEvent._create_1(type, init_1);
  }
  static BackgroundFetchedEvent _create_1(type, init) => JS(
      'BackgroundFetchedEvent', 'new BackgroundFetchedEvent(#,#)', type, init);

  final List<BackgroundFetchSettledFetch> fetches;

  Future updateUI(String title) =>
      promiseToFuture(JS("", "#.updateUI(#)", this, title));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#barprop
@deprecated // standard
@Native("BarProp")
class BarProp extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BarProp._() {
    throw new UnsupportedError("Not supported");
  }

  final bool visible;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BarcodeDetector")
class BarcodeDetector extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BarcodeDetector._() {
    throw new UnsupportedError("Not supported");
  }

  factory BarcodeDetector() {
    return BarcodeDetector._create_1();
  }
  static BarcodeDetector _create_1() =>
      JS('BarcodeDetector', 'new BarcodeDetector()');

  Future<List<DetectedBarcode>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<DetectedBarcode>>(
          JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLBaseElement")
class BaseElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory BaseElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory BaseElement() => JS(
      'returns:BaseElement;creates:BaseElement;new:true',
      '#.createElement(#)',
      document,
      "base");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BaseElement.created() : super.created();

  String href;

  String target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BatteryManager")
class BatteryManager extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BatteryManager._() {
    throw new UnsupportedError("Not supported");
  }

  final bool charging;

  final num chargingTime;

  final num dischargingTime;

  final num level;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BeforeInstallPromptEvent")
class BeforeInstallPromptEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeInstallPromptEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BeforeInstallPromptEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return BeforeInstallPromptEvent._create_1(type, eventInitDict_1);
    }
    return BeforeInstallPromptEvent._create_2(type);
  }
  static BeforeInstallPromptEvent _create_1(type, eventInitDict) => JS(
      'BeforeInstallPromptEvent',
      'new BeforeInstallPromptEvent(#,#)',
      type,
      eventInitDict);
  static BeforeInstallPromptEvent _create_2(type) =>
      JS('BeforeInstallPromptEvent', 'new BeforeInstallPromptEvent(#)', type);

  final List<String> platforms;

  Future<Map<String, dynamic>> get userChoice =>
      promiseToFutureAsMap(JS("", "#.userChoice", this));

  Future prompt() => promiseToFuture(JS("", "#.prompt()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BeforeUnloadEvent")
class BeforeUnloadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeUnloadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  // Shadowing definition.
  String get returnValue => JS("String", "#.returnValue", this);

  set returnValue(String value) {
    JS("void", "#.returnValue = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Blob")
class Blob extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Blob._() {
    throw new UnsupportedError("Not supported");
  }

  final int size;

  final String type;

  Blob slice([int start, int end, String contentType]) native;

  factory Blob(List blobParts, [String type, String endings]) {
    // TODO: validate that blobParts is a JS Array and convert if not.
    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
    // array to ArrayBuffer if it is a total view.
    if (type == null && endings == null) {
      return _create_1(blobParts);
    }
    var bag = _create_bag();
    if (type != null) _bag_set(bag, 'type', type);
    if (endings != null) _bag_set(bag, 'endings', endings);
    return _create_2(blobParts, bag);
  }

  static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts);
  static _create_2(parts, bag) => JS('Blob', 'new self.Blob(#, #)', parts, bag);

  static _create_bag() => JS('var', '{}');
  static _bag_set(bag, key, value) {
    JS('void', '#[#] = #', bag, key, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void BlobCallback(Blob blob);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BlobEvent")
class BlobEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BlobEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BlobEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return BlobEvent._create_1(type, eventInitDict_1);
  }
  static BlobEvent _create_1(type, eventInitDict) =>
      JS('BlobEvent', 'new BlobEvent(#,#)', type, eventInitDict);

  final Blob data;

  final num timecode;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTDescriptor")
class BluetoothRemoteGattDescriptor extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BluetoothRemoteGattDescriptor._() {
    throw new UnsupportedError("Not supported");
  }

  final _BluetoothRemoteGATTCharacteristic characteristic;

  final String uuid;

  final ByteData value;

  Future readValue() => promiseToFuture(JS("", "#.readValue()", this));

  Future writeValue(/*BufferSource*/ value) =>
      promiseToFuture(JS("", "#.writeValue(#)", this, value));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Body")
class Body extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Body._() {
    throw new UnsupportedError("Not supported");
  }

  final bool bodyUsed;

  Future arrayBuffer() => promiseToFuture(JS("", "#.arrayBuffer()", this));

  Future<Blob> blob() => promiseToFuture<Blob>(JS("", "#.blob()", this));

  Future<FormData> formData() =>
      promiseToFuture<FormData>(JS("", "#.formData()", this));

  Future json() => promiseToFuture(JS("", "#.json()", this));

  Future<String> text() => promiseToFuture<String>(JS("", "#.text()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLBodyElement")
class BodyElement extends HtmlElement implements WindowEventHandlers {
  // To suppress missing implicit constructor warnings.
  factory BodyElement._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  /**
   * Static factory designed to expose `resize` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  factory BodyElement() => JS(
      'returns:BodyElement;creates:BodyElement;new:true',
      '#.createElement(#)',
      document,
      "body");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BodyElement.created() : super.created();

  /// Stream of `blur` events handled by this [BodyElement].
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  /// Stream of `error` events handled by this [BodyElement].
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [BodyElement].
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `hashchange` events handled by this [BodyElement].
  ElementStream<Event> get onHashChange => hashChangeEvent.forElement(this);

  /// Stream of `load` events handled by this [BodyElement].
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  /// Stream of `message` events handled by this [BodyElement].
  ElementStream<MessageEvent> get onMessage => messageEvent.forElement(this);

  /// Stream of `offline` events handled by this [BodyElement].
  ElementStream<Event> get onOffline => offlineEvent.forElement(this);

  /// Stream of `online` events handled by this [BodyElement].
  ElementStream<Event> get onOnline => onlineEvent.forElement(this);

  /// Stream of `popstate` events handled by this [BodyElement].
  ElementStream<PopStateEvent> get onPopState => popStateEvent.forElement(this);

  /// Stream of `resize` events handled by this [BodyElement].
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `storage` events handled by this [BodyElement].
  ElementStream<StorageEvent> get onStorage => storageEvent.forElement(this);

  /// Stream of `unload` events handled by this [BodyElement].
  ElementStream<Event> get onUnload => unloadEvent.forElement(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BroadcastChannel")
class BroadcastChannel extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BroadcastChannel._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  factory BroadcastChannel(String name) {
    return BroadcastChannel._create_1(name);
  }
  static BroadcastChannel _create_1(name) =>
      JS('BroadcastChannel', 'new BroadcastChannel(#)', name);

  final String name;

  void close() native;

  void postMessage(Object message) native;

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BudgetState")
class BudgetState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BudgetState._() {
    throw new UnsupportedError("Not supported");
  }

  final num budgetAt;

  final int time;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLButtonElement")
class ButtonElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ButtonElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ButtonElement() => JS(
      'returns:ButtonElement;creates:ButtonElement;new:true',
      '#.createElement(#)',
      document,
      "button");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ButtonElement.created() : super.created();

  bool autofocus;

  bool disabled;

  final FormElement form;

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  String name;

  String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://dom.spec.whatwg.org/#cdatasection
@deprecated // deprecated
@Native("CDATASection")
class CDataSection extends Text {
  // To suppress missing implicit constructor warnings.
  factory CDataSection._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CacheStorage")
class CacheStorage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CacheStorage._() {
    throw new UnsupportedError("Not supported");
  }

  Future delete(String cacheName) =>
      promiseToFuture(JS("", "#.delete(#)", this, cacheName));

  Future has(String cacheName) =>
      promiseToFuture(JS("", "#.has(#)", this, cacheName));

  Future keys() => promiseToFuture(JS("", "#.keys()", this));

  Future match(/*RequestInfo*/ request, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.match(#, #)", this, request, options_dict));
  }

  Future open(String cacheName) =>
      promiseToFuture(JS("", "#.open(#)", this, cacheName));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CanMakePaymentEvent")
class CanMakePaymentEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory CanMakePaymentEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory CanMakePaymentEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return CanMakePaymentEvent._create_1(type, eventInitDict_1);
  }
  static CanMakePaymentEvent _create_1(type, eventInitDict) => JS(
      'CanMakePaymentEvent',
      'new CanMakePaymentEvent(#,#)',
      type,
      eventInitDict);

  final List methodData;

  final List modifiers;

  final String paymentRequestOrigin;

  final String topLevelOrigin;

  void respondWith(Future canMakePaymentResponse) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CanvasCaptureMediaStreamTrack")
class CanvasCaptureMediaStreamTrack extends MediaStreamTrack {
  // To suppress missing implicit constructor warnings.
  factory CanvasCaptureMediaStreamTrack._() {
    throw new UnsupportedError("Not supported");
  }

  final CanvasElement canvas;

  void requestFrame() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLCanvasElement")
class CanvasElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory CanvasElement._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `webglcontextlost` events to event
   * handlers that are not necessarily instances of [CanvasElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<gl.ContextEvent> webGlContextLostEvent =
      const EventStreamProvider<gl.ContextEvent>('webglcontextlost');

  /**
   * Static factory designed to expose `webglcontextrestored` events to event
   * handlers that are not necessarily instances of [CanvasElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<gl.ContextEvent> webGlContextRestoredEvent =
      const EventStreamProvider<gl.ContextEvent>('webglcontextrestored');

  factory CanvasElement({int width, int height}) {
    CanvasElement e = JS('returns:CanvasElement;creates:CanvasElement;new:true',
        '#.createElement(#)', document, "canvas");
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  CanvasElement.created() : super.created();

  /// The height of this canvas element in CSS pixels.
  int height;

  /// The width of this canvas element in CSS pixels.
  int width;

  MediaStream captureStream([num frameRate]) native;

  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object getContext(String contextId, [Map attributes]) {
    if (attributes != null) {
      var attributes_1 = convertDartToNative_Dictionary(attributes);
      return _getContext_1(contextId, attributes_1);
    }
    return _getContext_2(contextId);
  }

  @JSName('getContext')
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object _getContext_1(contextId, attributes) native;
  @JSName('getContext')
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object _getContext_2(contextId) native;

  @JSName('toDataURL')
  String _toDataUrl(String type, [arguments_OR_quality]) native;

  OffscreenCanvas transferControlToOffscreen() native;

  /// Stream of `webglcontextlost` events handled by this [CanvasElement].
  ElementStream<gl.ContextEvent> get onWebGlContextLost =>
      webGlContextLostEvent.forElement(this);

  /// Stream of `webglcontextrestored` events handled by this [CanvasElement].
  ElementStream<gl.ContextEvent> get onWebGlContextRestored =>
      webGlContextRestoredEvent.forElement(this);

  /** An API for drawing on this canvas. */
  CanvasRenderingContext2D get context2D =>
      JS('Null|CanvasRenderingContext2D', '#.getContext(#)', this, '2d');

  /**
   * Returns a new Web GL context for this canvas.
   *
   * ## Other resources
   *
   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
   *   from HTML5Rocks.
   * * [WebGL homepage](http://get.webgl.org/).
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  gl.RenderingContext getContext3d(
      {alpha: true,
      depth: true,
      stencil: false,
      antialias: true,
      premultipliedAlpha: true,
      preserveDrawingBuffer: false}) {
    var options = {
      'alpha': alpha,
      'depth': depth,
      'stencil': stencil,
      'antialias': antialias,
      'premultipliedAlpha': premultipliedAlpha,
      'preserveDrawingBuffer': preserveDrawingBuffer,
    };
    var context = getContext('webgl', options);
    if (context == null) {
      context = getContext('experimental-webgl', options);
    }
    return context;
  }

  /**
   * Returns a data URI containing a representation of the image in the
   * format specified by type (defaults to 'image/png').
   *
   * Data Uri format is as follow
   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
   *
   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
   * the default value is used. Note: the default value varies by browser.
   *
   * If the height or width of this canvas element is 0, then 'data:' is
   * returned, representing no data.
   *
   * If the type requested is not 'image/png', and the returned value is
   * 'data:image/png', then the requested type is not supported.
   *
   * Example usage:
   *
   *     CanvasElement canvas = new CanvasElement();
   *     var ctx = canvas.context2D
   *     ..fillStyle = "rgb(200,0,0)"
   *     ..fillRect(10, 10, 55, 50);
   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
   *     // The Data Uri would look similar to
   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
   *     //Create a new image element from the data URI.
   *     var img = new ImageElement();
   *     img.src = dataUrl;
   *     document.body.children.add(img);
   *
   * See also:
   *
   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
   *
   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
   *
   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
   */
  String toDataUrl([String type = 'image/png', num quality]) =>
      _toDataUrl(type, quality);

  @JSName('toBlob')
  void _toBlob(BlobCallback callback, String type, [Object arguments]) native;

  Future<Blob> toBlob(String type, [Object arguments]) {
    var completer = new Completer<Blob>();
    _toBlob((value) {
      completer.complete(value);
    }, type, arguments);
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An opaque canvas object representing a gradient.
 *
 * Created by calling [createLinearGradient] or [createRadialGradient] on a
 * [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     ctx.clearRect(0, 0, 600, 600);
 *     ctx.save();
 *     // Create radial gradient.
 *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
 *     gradient.addColorStop(0, '#000');
 *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
 *     // Assign gradients to fill.
 *     ctx.fillStyle = gradient;
 *     // Draw a rectangle with a gradient fill.
 *     ctx.fillRect(0, 0, 600, 600);
 *     ctx.save();
 *     document.body.children.add(canvas);
 *
 * See also:
 *
 * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
 * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
 *   from WHATWG.
 * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
 */
@Native("CanvasGradient")
class CanvasGradient extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CanvasGradient._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Adds a color stop to this gradient at the offset.
   *
   * The [offset] can range between 0.0 and 1.0.
   *
   * See also:
   *
   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
   */
  void addColorStop(num offset, String color) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An opaque object representing a pattern of image, canvas, or video.
 *
 * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     var img = new ImageElement();
 *     // Image src needs to be loaded before pattern is applied.
 *     img.onLoad.listen((event) {
 *       // When the image is loaded, create a pattern
 *       // from the ImageElement.
 *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
 *       ctx.rect(0, 0, canvas.width, canvas.height);
 *       ctx.fillStyle = pattern;
 *       ctx.fill();
 *     });
 *     img.src = "images/foo.jpg";
 *     document.body.children.add(canvas);
 *
 * See also:
 * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
 * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
 *   from WHATWG.
 * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
 */
@Native("CanvasPattern")
class CanvasPattern extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CanvasPattern._() {
    throw new UnsupportedError("Not supported");
  }

  void setTransform(Matrix transform) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class CanvasRenderingContext {
  CanvasElement get canvas;
}

@Native("CanvasRenderingContext2D")
class CanvasRenderingContext2D extends Interceptor
    implements CanvasRenderingContext {
  // To suppress missing implicit constructor warnings.
  factory CanvasRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  final CanvasElement canvas;

  Matrix currentTransform;

  String direction;

  @Creates('String|CanvasGradient|CanvasPattern')
  @Returns('String|CanvasGradient|CanvasPattern')
  Object fillStyle;

  String filter;

  String font;

  num globalAlpha;

  String globalCompositeOperation;

  /**
   * Whether images and patterns on this canvas will be smoothed when this
   * canvas is scaled.
   *
   * ## Other resources
   *
   * * [Image
   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
   *   from WHATWG.
   */
  bool imageSmoothingEnabled;

  String imageSmoothingQuality;

  String lineCap;

  String lineJoin;

  num lineWidth;

  num miterLimit;

  num shadowBlur;

  String shadowColor;

  num shadowOffsetX;

  num shadowOffsetY;

  @Creates('String|CanvasGradient|CanvasPattern')
  @Returns('String|CanvasGradient|CanvasPattern')
  Object strokeStyle;

  String textAlign;

  String textBaseline;

  void addHitRegion([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _addHitRegion_1(options_1);
      return;
    }
    _addHitRegion_2();
    return;
  }

  @JSName('addHitRegion')
  void _addHitRegion_1(options) native;
  @JSName('addHitRegion')
  void _addHitRegion_2() native;

  void beginPath() native;

  void clearHitRegions() native;

  void clearRect(num x, num y, num width, num height) native;

  void clip([path_OR_winding, String winding]) native;

  @Creates('ImageData|=Object')
  ImageData createImageData(data_OR_imagedata_OR_sw,
      [int sh_OR_sw,
      imageDataColorSettings_OR_sh,
      Map imageDataColorSettings]) {
    if ((data_OR_imagedata_OR_sw is ImageData) &&
        sh_OR_sw == null &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      var imagedata_1 = convertDartToNative_ImageData(data_OR_imagedata_OR_sw);
      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
    }
    if (sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      return convertNativeToDart_ImageData(
          _createImageData_2(data_OR_imagedata_OR_sw, sh_OR_sw));
    }
    if ((imageDataColorSettings_OR_sh is Map) &&
        sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings == null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings_OR_sh);
      return convertNativeToDart_ImageData(_createImageData_3(
          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_1));
    }
    if ((imageDataColorSettings_OR_sh is int) &&
        sh_OR_sw != null &&
        data_OR_imagedata_OR_sw != null &&
        imageDataColorSettings == null) {
      return convertNativeToDart_ImageData(_createImageData_4(
          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_OR_sh));
    }
    if (imageDataColorSettings != null &&
        (imageDataColorSettings_OR_sh is int) &&
        sh_OR_sw != null &&
        data_OR_imagedata_OR_sw != null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings);
      return convertNativeToDart_ImageData(_createImageData_5(
          data_OR_imagedata_OR_sw,
          sh_OR_sw,
          imageDataColorSettings_OR_sh,
          imageDataColorSettings_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_1(imagedata) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_2(int sw, sh) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_3(int sw, sh, imageDataColorSettings) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_4(data, sw, int sh) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_5(data, sw, int sh, imageDataColorSettings) native;

  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  CanvasPattern createPattern(Object image, String repetitionType) native;

  CanvasGradient createRadialGradient(
      num x0, num y0, num r0, num x1, num y1, num r1) native;

  void drawFocusIfNeeded(element_OR_path, [Element element]) native;

  void fill([path_OR_winding, String winding]) native;

  void fillRect(num x, num y, num width, num height) native;

  Map getContextAttributes() {
    return convertNativeToDart_Dictionary(_getContextAttributes_1());
  }

  @JSName('getContextAttributes')
  _getContextAttributes_1() native;

  @Creates('ImageData|=Object')
  ImageData getImageData(int sx, int sy, int sw, int sh) {
    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
  }

  @JSName('getImageData')
  @Creates('ImageData|=Object')
  _getImageData_1(sx, sy, sw, sh) native;

  @JSName('getLineDash')
  List<num> _getLineDash() native;

  bool isContextLost() native;

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
      native;

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  TextMetrics measureText(String text) native;

  void putImageData(ImageData imagedata, int dx, int dy,
      [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) {
    if (dirtyX == null &&
        dirtyY == null &&
        dirtyWidth == null &&
        dirtyHeight == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_1(imagedata_1, dx, dy);
      return;
    }
    if (dirtyHeight != null &&
        dirtyWidth != null &&
        dirtyY != null &&
        dirtyX != null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_2(
          imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('putImageData')
  void _putImageData_1(imagedata, dx, dy) native;
  @JSName('putImageData')
  void _putImageData_2(
      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;

  void removeHitRegion(String id) native;

  void resetTransform() native;

  void restore() native;

  void rotate(num angle) native;

  void save() native;

  void scale(num x, num y) native;

  void scrollPathIntoView([Path2D path]) native;

  void setTransform(num a, num b, num c, num d, num e, num f) native;

  void stroke([Path2D path]) native;

  void strokeRect(num x, num y, num width, num height) native;

  void strokeText(String text, num x, num y, [num maxWidth]) native;

  void transform(num a, num b, num c, num d, num e, num f) native;

  void translate(num x, num y) native;

  // From CanvasPath

  @JSName('arc')
  void _arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;

  ImageData createImageDataFromImageData(ImageData imagedata) =>
      JS('ImageData', '#.createImageData(#)', this, imagedata);

  /**
   * Sets the color used inside shapes.
   * [r], [g], [b] are 0-255, [a] is 0-1.
   */
  void setFillColorRgb(int r, int g, int b, [num a = 1]) {
    this.fillStyle = 'rgba($r, $g, $b, $a)';
  }

  /**
   * Sets the color used inside shapes.
   * [h] is in degrees, 0-360.
   * [s], [l] are in percent, 0-100.
   * [a] is 0-1.
   */
  void setFillColorHsl(int h, num s, num l, [num a = 1]) {
    this.fillStyle = 'hsla($h, $s%, $l%, $a)';
  }

  /**
   * Sets the color used for stroking shapes.
   * [r], [g], [b] are 0-255, [a] is 0-1.
   */
  void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
    this.strokeStyle = 'rgba($r, $g, $b, $a)';
  }

  /**
   * Sets the color used for stroking shapes.
   * [h] is in degrees, 0-360.
   * [s], [l] are in percent, 0-100.
   * [a] is 0-1.
   */
  void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
    this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
  }

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      [bool anticlockwise = false]) {
    // TODO(terry): This should not be needed: dartbug.com/20939.
    JS('void', '#.arc(#, #, #, #, #, #)', this, x, y, radius, startAngle,
        endAngle, anticlockwise);
  }

  CanvasPattern createPatternFromImage(
          ImageElement image, String repetitionType) =>
      JS('CanvasPattern', '#.createPattern(#, #)', this, image, repetitionType);

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image will be drawn to an area of this canvas defined by
   * [destRect]. [sourceRect] defines the region of the source image that is
   * drawn.
   * If [sourceRect] is not provided, then
   * the entire rectangular image from [source] will be drawn to this context.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *     img.width = 100;
   *     img.height = 100;
   *
   *     // Scale the image to 20x20.
   *     ctx.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
   *
   *     VideoElement video = document.query('video');
   *     video.width = 100;
   *     video.height = 100;
   *     // Take the middle 20x20 pixels from the video and stretch them.
   *     ctx.drawImageToRect(video, new Rectangle(50, 50, 100, 100),
   *         sourceRect: new Rectangle(40, 40, 20, 20));
   *
   *     // Draw the top 100x20 pixels from the otherCanvas.
   *     CanvasElement otherCanvas = document.query('canvas');
   *     ctx.drawImageToRect(otherCanvas, new Rectangle(0, 0, 100, 20),
   *         sourceRect: new Rectangle(0, 0, 100, 20));
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  void drawImageToRect(CanvasImageSource source, Rectangle destRect,
      {Rectangle sourceRect}) {
    if (sourceRect == null) {
      drawImageScaled(
          source, destRect.left, destRect.top, destRect.width, destRect.height);
    } else {
      drawImageScaledFromSource(
          source,
          sourceRect.left,
          sourceRect.top,
          sourceRect.width,
          sourceRect.height,
          destRect.left,
          destRect.top,
          destRect.width,
          destRect.height);
    }
  }

  /**
   * Draws an image from a CanvasImageSource to this canvas.
   *
   * The entire image from [source] will be drawn to this context with its top
   * left corner at the point ([destX], [destY]). If the image is
   * larger than canvas will allow, the image will be clipped to fit the
   * available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *
   *     ctx.drawImage(img, 100, 100);
   *
   *     VideoElement video = document.query('video');
   *     ctx.drawImage(video, 0, 0);
   *
   *     CanvasElement otherCanvas = document.query('canvas');
   *     otherCanvas.width = 100;
   *     otherCanvas.height = 100;
   *     ctx.drawImage(otherCanvas, 590, 590); // will get clipped
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @JSName('drawImage')
  void drawImage(CanvasImageSource source, num destX, num destY) native;

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image will be drawn to this context with its top left corner at the
   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
   * [destHeight] tall.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *     img.width = 100;
   *     img.height = 100;
   *
   *     // Scale the image to 300x50 at the point (20, 20)
   *     ctx.drawImageScaled(img, 20, 20, 300, 50);
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @JSName('drawImage')
  void drawImageScaled(CanvasImageSource source, num destX, num destY,
      num destWidth, num destHeight) native;

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image is a region of [source] that is [sourceWidth] wide and
   * [destHeight] tall with top left corner at ([sourceX], [sourceY]).
   * The image will be drawn to this context with its top left corner at the
   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
   * [destHeight] tall.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     VideoElement video = document.query('video');
   *     video.width = 100;
   *     video.height = 100;
   *     // Take the middle 20x20 pixels from the video and stretch them.
   *     ctx.drawImageScaledFromSource(video, 40, 40, 20, 20, 50, 50, 100, 100);
   *
   *     // Draw the top 100x20 pixels from the otherCanvas to this one.
   *     CanvasElement otherCanvas = document.query('canvas');
   *     ctx.drawImageScaledFromSource(otherCanvas, 0, 0, 100, 20, 0, 0, 100, 20);
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @JSName('drawImage')
  void drawImageScaledFromSource(
      CanvasImageSource source,
      num sourceX,
      num sourceY,
      num sourceWidth,
      num sourceHeight,
      num destX,
      num destY,
      num destWidth,
      num destHeight) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
  // needs to be polyfilled.
  num get lineDashOffset =>
      JS('num', '#.lineDashOffset || #.webkitLineDashOffset', this, this);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
  // needs to be polyfilled.
  set lineDashOffset(num value) {
    JS(
        'void',
        'typeof #.lineDashOffset != "undefined" ? #.lineDashOffset = # : '
        '#.webkitLineDashOffset = #',
        this,
        this,
        value,
        this,
        value);
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  List<num> getLineDash() {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    if (JS('bool', '!!#.getLineDash', this)) {
      return JS('List<num>', '#.getLineDash()', this);
    } else if (JS('bool', '!!#.webkitLineDash', this)) {
      return JS('List<num>', '#.webkitLineDash', this);
    }
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  void setLineDash(List<num> dash) {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    if (JS('bool', '!!#.setLineDash', this)) {
      JS('void', '#.setLineDash(#)', this, dash);
    } else if (JS('bool', '!!#.webkitLineDash', this)) {
      JS('void', '#.webkitLineDash = #', this, dash);
    }
  }

  /**
   * Draws text to the canvas.
   *
   * The text is drawn starting at coordinates ([x], [y]).
   * If [maxWidth] is provided and the [text] is computed to be wider than
   * [maxWidth], then the drawn text is scaled down horizontally to fit.
   *
   * The text uses the current [CanvasRenderingContext2D.font] property for font
   * options, such as typeface and size, and the current
   * [CanvasRenderingContext2D.fillStyle] for style options such as color.
   * The current [CanvasRenderingContext2D.textAlign] and
   * [CanvasRenderingContext2D.textBaseLine] properties are also applied to the
   * drawn text.
   */
  void fillText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      JS('void', '#.fillText(#, #, #, #)', this, text, x, y, maxWidth);
    } else {
      JS('void', '#.fillText(#, #, #)', this, text, x, y);
    }
  }

  /** Deprecated always returns 1.0 */
  @deprecated
  double get backingStorePixelRatio => 1.0;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CharacterData")
class CharacterData extends Node
    implements NonDocumentTypeChildNode, ChildNode {
  // To suppress missing implicit constructor warnings.
  factory CharacterData._() {
    throw new UnsupportedError("Not supported");
  }

  String data;

  final int length;

  void appendData(String data) native;

  void deleteData(int offset, int count) native;

  void insertData(int offset, String data) native;

  void replaceData(int offset, int count, String data) native;

  String substringData(int offset, int count) native;

  // From ChildNode

  void after(Object nodes) native;

  void before(Object nodes) native;

  // From NonDocumentTypeChildNode

  final Element nextElementSibling;

  final Element previousElementSibling;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ChildNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ChildNode._() {
    throw new UnsupportedError("Not supported");
  }

  void after(Object nodes);

  void before(Object nodes);

  void remove();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Client")
class Client extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Client._() {
    throw new UnsupportedError("Not supported");
  }

  final String frameType;

  final String id;

  final String type;

  final String url;

  void postMessage(Object message, [List<Object> transfer]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Clients")
class Clients extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Clients._() {
    throw new UnsupportedError("Not supported");
  }

  Future claim() => promiseToFuture(JS("", "#.claim()", this));

  Future get(String id) => promiseToFuture(JS("", "#.get(#)", this, id));

  Future<List<Client>> matchAll([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<List<Client>>(
        JS("", "#.matchAll(#)", this, options_dict));
  }

  Future<WindowClient> openWindow(String url) =>
      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ClipboardEvent")
class ClipboardEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ClipboardEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ClipboardEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ClipboardEvent._create_1(type, eventInitDict_1);
    }
    return ClipboardEvent._create_2(type);
  }
  static ClipboardEvent _create_1(type, eventInitDict) =>
      JS('ClipboardEvent', 'new ClipboardEvent(#,#)', type, eventInitDict);
  static ClipboardEvent _create_2(type) =>
      JS('ClipboardEvent', 'new ClipboardEvent(#)', type);

  final DataTransfer clipboardData;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CloseEvent")
class CloseEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory CloseEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory CloseEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CloseEvent._create_1(type, eventInitDict_1);
    }
    return CloseEvent._create_2(type);
  }
  static CloseEvent _create_1(type, eventInitDict) =>
      JS('CloseEvent', 'new CloseEvent(#,#)', type, eventInitDict);
  static CloseEvent _create_2(type) =>
      JS('CloseEvent', 'new CloseEvent(#)', type);

  final int code;

  final String reason;

  final bool wasClean;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Comment")
class Comment extends CharacterData {
  factory Comment([String data]) {
    return JS('returns:Comment;depends:none;effects:none;new:true',
        '#.createComment(#)', document, data == null ? "" : data);
  }
  // To suppress missing implicit constructor warnings.
  factory Comment._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("CompositionEvent")
class CompositionEvent extends UIEvent {
  factory CompositionEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Window view,
      String data,
      String locale}) {
    if (view == null) {
      view = window;
    }
    CompositionEvent e = document._createEvent("CompositionEvent");

    if (Device.isFirefox) {
      // Firefox requires the locale parameter that isn't supported elsewhere.
      JS('void', '#.initCompositionEvent(#, #, #, #, #, #)', e, type, canBubble,
          cancelable, view, data, locale);
    } else {
      e._initCompositionEvent(type, canBubble, cancelable, view, data);
    }

    return e;
  }

  factory CompositionEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CompositionEvent._create_1(type, eventInitDict_1);
    }
    return CompositionEvent._create_2(type);
  }
  static CompositionEvent _create_1(type, eventInitDict) =>
      JS('CompositionEvent', 'new CompositionEvent(#,#)', type, eventInitDict);
  static CompositionEvent _create_2(type) =>
      JS('CompositionEvent', 'new CompositionEvent(#)', type);

  final String data;

  @JSName('initCompositionEvent')
  void _initCompositionEvent(String type, bool bubbles, bool cancelable,
      Window view, String data) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Native("HTMLContentElement")
class ContentElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ContentElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ContentElement() => document.createElement("content");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ContentElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('content');

  String select;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CookieStore")
class CookieStore extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CookieStore._() {
    throw new UnsupportedError("Not supported");
  }

  Future getAll([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.getAll(#)", this, options_dict));
  }

  Future set(String name, String value, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.set(#, #, #)", this, name, value, options_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Coordinates")
class Coordinates extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Coordinates._() {
    throw new UnsupportedError("Not supported");
  }

  final num accuracy;

  final num altitude;

  final num altitudeAccuracy;

  final num heading;

  final num latitude;

  final num longitude;

  final num speed;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Credential")
class Credential extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Credential._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CredentialUserData")
class CredentialUserData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CredentialUserData._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('iconURL')
  final String iconUrl;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CredentialsContainer")
class CredentialsContainer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CredentialsContainer._() {
    throw new UnsupportedError("Not supported");
  }

  Future create([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.create(#)", this, options_dict));
  }

  Future get([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.get(#)", this, options_dict));
  }

  Future preventSilentAccess() =>
      promiseToFuture(JS("", "#.preventSilentAccess()", this));

  Future requireUserMediation() =>
      promiseToFuture(JS("", "#.requireUserMediation()", this));

  Future store(Credential credential) =>
      promiseToFuture(JS("", "#.store(#)", this, credential));
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("Crypto")
class Crypto extends Interceptor {
  TypedData getRandomValues(TypedData array) {
    return _getRandomValues(array);
  }

  // To suppress missing implicit constructor warnings.
  factory Crypto._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '!!(window.crypto && window.crypto.getRandomValues)');

  final _SubtleCrypto subtle;

  @JSName('getRandomValues')
  @Creates('TypedData')
  @Returns('TypedData|Null')
  TypedData _getRandomValues(TypedData array) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CryptoKey")
class CryptoKey extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CryptoKey._() {
    throw new UnsupportedError("Not supported");
  }

  @Creates('Null')
  final Object algorithm;

  final bool extractable;

  final String type;

  final Object usages;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSS")
class Css extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Css._() {
    throw new UnsupportedError("Not supported");
  }

  static final _Worklet paintWorklet;

  static CssUnitValue Hz(num value) native;

  static CssUnitValue ch(num value) native;

  static CssUnitValue cm(num value) native;

  static CssUnitValue deg(num value) native;

  static CssUnitValue dpcm(num value) native;

  static CssUnitValue dpi(num value) native;

  static CssUnitValue dppx(num value) native;

  static CssUnitValue em(num value) native;

  static String escape(String ident) native;

  static CssUnitValue ex(num value) native;

  static CssUnitValue fr(num value) native;

  static CssUnitValue grad(num value) native;

  @JSName('in')
  static CssUnitValue inch(num value) native;

  static CssUnitValue kHz(num value) native;

  static CssUnitValue mm(num value) native;

  static CssUnitValue ms(num value) native;

  static CssUnitValue number(num value) native;

  static CssUnitValue pc(num value) native;

  static CssUnitValue percent(num value) native;

  static CssUnitValue pt(num value) native;

  static CssUnitValue px(num value) native;

  static CssUnitValue rad(num value) native;

  static void registerProperty(Map descriptor) {
    var descriptor_1 = convertDartToNative_Dictionary(descriptor);
    _registerProperty_1(descriptor_1);
    return;
  }

  @JSName('registerProperty')
  static void _registerProperty_1(descriptor) native;

  static CssUnitValue rem(num value) native;

  static CssUnitValue s(num value) native;

  static bool supports(String property, String value) native;

  @JSName('supports')
  static bool supportsCondition(String conditionText) native;

  static CssUnitValue turn(num value) native;

  static CssUnitValue vh(num value) native;

  static CssUnitValue vmax(num value) native;

  static CssUnitValue vmin(num value) native;

  static CssUnitValue vw(num value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSCharsetRule")
class CssCharsetRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssCharsetRule._() {
    throw new UnsupportedError("Not supported");
  }

  String encoding;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSConditionRule")
class CssConditionRule extends CssGroupingRule {
  // To suppress missing implicit constructor warnings.
  factory CssConditionRule._() {
    throw new UnsupportedError("Not supported");
  }

  final String conditionText;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSFontFaceRule")
class CssFontFaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssFontFaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSGroupingRule")
class CssGroupingRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssGroupingRule._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  void deleteRule(int index) native;

  int insertRule(String rule, int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSImageValue")
class CssImageValue extends CssResourceValue {
  // To suppress missing implicit constructor warnings.
  factory CssImageValue._() {
    throw new UnsupportedError("Not supported");
  }

  final num intrinsicHeight;

  final num intrinsicRatio;

  final num intrinsicWidth;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSImportRule")
class CssImportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssImportRule._() {
    throw new UnsupportedError("Not supported");
  }

  final String href;

  final MediaList media;

  final CssStyleSheet styleSheet;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule")
class CssKeyframeRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframeRule._() {
    throw new UnsupportedError("Not supported");
  }

  String keyText;

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule")
class CssKeyframesRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframesRule._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  String name;

  CssKeyframeRule __getter__(int index) native;

  void appendRule(String rule) native;

  void deleteRule(String select) native;

  CssKeyframeRule findRule(String select) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSKeywordValue")
class CssKeywordValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssKeywordValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssKeywordValue(String keyword) {
    return CssKeywordValue._create_1(keyword);
  }
  static CssKeywordValue _create_1(keyword) =>
      JS('CssKeywordValue', 'new CSSKeywordValue(#)', keyword);

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSMatrixComponent")
class CssMatrixComponent extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssMatrixComponent._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssMatrixComponent(DomMatrixReadOnly matrix, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return CssMatrixComponent._create_1(matrix, options_1);
    }
    return CssMatrixComponent._create_2(matrix);
  }
  static CssMatrixComponent _create_1(matrix, options) =>
      JS('CssMatrixComponent', 'new CSSMatrixComponent(#,#)', matrix, options);
  static CssMatrixComponent _create_2(matrix) =>
      JS('CssMatrixComponent', 'new CSSMatrixComponent(#)', matrix);

  DomMatrix matrix;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSMediaRule")
class CssMediaRule extends CssConditionRule {
  // To suppress missing implicit constructor warnings.
  factory CssMediaRule._() {
    throw new UnsupportedError("Not supported");
  }

  final MediaList media;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSNamespaceRule")
class CssNamespaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssNamespaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('namespaceURI')
  final String namespaceUri;

  final String prefix;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSNumericValue")
class CssNumericValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssNumericValue._() {
    throw new UnsupportedError("Not supported");
  }

  CssNumericValue add(CssNumericValue value) native;

  CssNumericValue div(num value) native;

  CssNumericValue mul(num value) native;

  static CssNumericValue parse(String cssText) native;

  CssNumericValue sub(CssNumericValue value) native;

  CssNumericValue to(String unit) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSPageRule")
class CssPageRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssPageRule._() {
    throw new UnsupportedError("Not supported");
  }

  String selectorText;

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSPerspective")
class CssPerspective extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssPerspective._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssPerspective(CssNumericValue length) {
    return CssPerspective._create_1(length);
  }
  static CssPerspective _create_1(length) =>
      JS('CssPerspective', 'new CSSPerspective(#)', length);

  CssNumericValue length;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSPositionValue")
class CssPositionValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssPositionValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssPositionValue(CssNumericValue x, CssNumericValue y) {
    return CssPositionValue._create_1(x, y);
  }
  static CssPositionValue _create_1(x, y) =>
      JS('CssPositionValue', 'new CSSPositionValue(#,#)', x, y);

  CssNumericValue x;

  CssNumericValue y;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSResourceValue")
class CssResourceValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssResourceValue._() {
    throw new UnsupportedError("Not supported");
  }

  final String state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSRotation")
class CssRotation extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssRotation._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssRotation(angleValue_OR_x, [num y, num z, CssNumericValue angle]) {
    if ((angleValue_OR_x is CssNumericValue) &&
        y == null &&
        z == null &&
        angle == null) {
      return CssRotation._create_1(angleValue_OR_x);
    }
    if ((angle is CssNumericValue) &&
        (z is num) &&
        (y is num) &&
        (angleValue_OR_x is num)) {
      return CssRotation._create_2(angleValue_OR_x, y, z, angle);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssRotation _create_1(angleValue_OR_x) =>
      JS('CssRotation', 'new CSSRotation(#)', angleValue_OR_x);
  static CssRotation _create_2(angleValue_OR_x, y, z, angle) => JS(
      'CssRotation', 'new CSSRotation(#,#,#,#)', angleValue_OR_x, y, z, angle);

  CssNumericValue angle;

  num x;

  num y;

  num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSRule")
class CssRule extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssRule._() {
    throw new UnsupportedError("Not supported");
  }

  static const int CHARSET_RULE = 2;

  static const int FONT_FACE_RULE = 5;

  static const int IMPORT_RULE = 3;

  static const int KEYFRAMES_RULE = 7;

  static const int KEYFRAME_RULE = 8;

  static const int MEDIA_RULE = 4;

  static const int NAMESPACE_RULE = 10;

  static const int PAGE_RULE = 6;

  static const int STYLE_RULE = 1;

  static const int SUPPORTS_RULE = 12;

  static const int VIEWPORT_RULE = 15;

  String cssText;

  final CssRule parentRule;

  final CssStyleSheet parentStyleSheet;

  final int type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSScale")
class CssScale extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssScale._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssScale(num x, num y, [num z]) {
    if ((y is num) && (x is num) && z == null) {
      return CssScale._create_1(x, y);
    }
    if ((z is num) && (y is num) && (x is num)) {
      return CssScale._create_2(x, y, z);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssScale _create_1(x, y) => JS('CssScale', 'new CSSScale(#,#)', x, y);
  static CssScale _create_2(x, y, z) =>
      JS('CssScale', 'new CSSScale(#,#,#)', x, y, z);

  num x;

  num y;

  num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSSkew")
class CssSkew extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssSkew._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssSkew(CssNumericValue ax, CssNumericValue ay) {
    return CssSkew._create_1(ax, ay);
  }
  static CssSkew _create_1(ax, ay) => JS('CssSkew', 'new CSSSkew(#,#)', ax, ay);

  CssNumericValue ax;

  CssNumericValue ay;
}

// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
// The template file was generated by scripts/css_code_generator.py

// Source of CSS properties:
//   CSSPropertyNames.in

@Native("CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties")
class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
  factory CssStyleDeclaration() => new CssStyleDeclaration.css('');

  factory CssStyleDeclaration.css(String css) {
    final style = new DivElement().style;
    style.cssText = css;
    return style;
  }

  /// Returns the value of the property if the provided *CSS* property
  /// name is supported on this element and if the value is set. Otherwise
  /// returns an empty string.
  ///
  /// Please note the property name uses camelCase, not-hyphens.
  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValueHelper(propertyName);
    return propValue ?? '';
  }

  String _getPropertyValueHelper(String propertyName) {
    return _getPropertyValue(_browserPropertyName(propertyName));
  }

  /**
   * Returns true if the provided *CSS* property name is supported on this
   * element.
   *
   * Please note the property name camelCase, not-hyphens. This
   * method returns true if the property is accessible via an unprefixed _or_
   * prefixed property.
   */
  bool supportsProperty(String propertyName) {
    return _supportsProperty(propertyName) ||
        _supportsProperty(_camelCase("${Device.cssPrefix}$propertyName"));
  }

  bool _supportsProperty(String propertyName) {
    return JS('bool', '# in #', propertyName, this);
  }

  void setProperty(String propertyName, String value, [String priority]) {
    return _setPropertyHelper(
        _browserPropertyName(propertyName), value, priority);
  }

  String _browserPropertyName(String propertyName) {
    String name = _readCache(propertyName);
    if (name is String) return name;
    name = _supportedBrowserPropertyName(propertyName);
    _writeCache(propertyName, name);
    return name;
  }

  String _supportedBrowserPropertyName(String propertyName) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return propertyName;
    }
    var prefixed = "${Device.cssPrefix}$propertyName";
    if (_supportsProperty(prefixed)) {
      return prefixed;
    }
    // May be a CSS variable, just use it as provided.
    return propertyName;
  }

  static final _propertyCache = JS('', '{}');
  static String _readCache(String key) =>
      JS('String|Null', '#[#]', _propertyCache, key);
  static void _writeCache(String key, String value) {
    JS('void', '#[#] = #', _propertyCache, key, value);
  }

  static String _camelCase(String hyphenated) {
    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);
    return JS(
        'String',
        r'#.replace(/-([\da-z])/ig,'
        r'function(_, letter) { return letter.toUpperCase();})',
        replacedMs);
  }

  void _setPropertyHelper(String propertyName, String value,
      [String priority]) {
    if (value == null) value = '';
    if (priority == null) priority = '';
    JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    return document.body.style.supportsProperty('transition');
  }

  // To suppress missing implicit constructor warnings.
  factory CssStyleDeclaration._() {
    throw new UnsupportedError("Not supported");
  }

  String cssFloat;

  String cssText;

  final int length;

  final CssRule parentRule;

  String getPropertyPriority(String property) native;

  @JSName('getPropertyValue')
  String _getPropertyValue(String property) native;

  String item(int index) native;

  String removeProperty(String property) native;

  /** Gets the value of "background" */
  String get background => this._background;

  /** Sets the value of "background" */
  set background(String value) {
    _background = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('background')
  String _background;

  /** Gets the value of "background-attachment" */
  String get backgroundAttachment => this._backgroundAttachment;

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _backgroundAttachment = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundAttachment')
  String _backgroundAttachment;

  /** Gets the value of "background-color" */
  String get backgroundColor => this._backgroundColor;

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _backgroundColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundColor')
  String _backgroundColor;

  /** Gets the value of "background-image" */
  String get backgroundImage => this._backgroundImage;

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _backgroundImage = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundImage')
  String _backgroundImage;

  /** Gets the value of "background-position" */
  String get backgroundPosition => this._backgroundPosition;

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _backgroundPosition = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundPosition')
  String _backgroundPosition;

  /** Gets the value of "background-repeat" */
  String get backgroundRepeat => this._backgroundRepeat;

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _backgroundRepeat = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundRepeat')
  String _backgroundRepeat;

  /** Gets the value of "border" */
  String get border => this._border;

  /** Sets the value of "border" */
  set border(String value) {
    _border = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('border')
  String _border;

  /** Gets the value of "border-bottom" */
  String get borderBottom => this._borderBottom;

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _borderBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottom')
  String _borderBottom;

  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor => this._borderBottomColor;

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _borderBottomColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomColor')
  String _borderBottomColor;

  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle => this._borderBottomStyle;

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _borderBottomStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomStyle')
  String _borderBottomStyle;

  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth => this._borderBottomWidth;

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _borderBottomWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomWidth')
  String _borderBottomWidth;

  /** Gets the value of "border-collapse" */
  String get borderCollapse => this._borderCollapse;

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _borderCollapse = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderCollapse')
  String _borderCollapse;

  /** Gets the value of "border-color" */
  String get borderColor => this._borderColor;

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _borderColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderColor')
  String _borderColor;

  /** Gets the value of "border-left" */
  String get borderLeft => this._borderLeft;

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _borderLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeft')
  String _borderLeft;

  /** Gets the value of "border-left-color" */
  String get borderLeftColor => this._borderLeftColor;

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _borderLeftColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftColor')
  String _borderLeftColor;

  /** Gets the value of "border-left-style" */
  String get borderLeftStyle => this._borderLeftStyle;

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _borderLeftStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftStyle')
  String _borderLeftStyle;

  /** Gets the value of "border-left-width" */
  String get borderLeftWidth => this._borderLeftWidth;

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _borderLeftWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftWidth')
  String _borderLeftWidth;

  /** Gets the value of "border-right" */
  String get borderRight => this._borderRight;

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _borderRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRight')
  String _borderRight;

  /** Gets the value of "border-right-color" */
  String get borderRightColor => this._borderRightColor;

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _borderRightColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightColor')
  String _borderRightColor;

  /** Gets the value of "border-right-style" */
  String get borderRightStyle => this._borderRightStyle;

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _borderRightStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightStyle')
  String _borderRightStyle;

  /** Gets the value of "border-right-width" */
  String get borderRightWidth => this._borderRightWidth;

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _borderRightWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightWidth')
  String _borderRightWidth;

  /** Gets the value of "border-spacing" */
  String get borderSpacing => this._borderSpacing;

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _borderSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderSpacing')
  String _borderSpacing;

  /** Gets the value of "border-style" */
  String get borderStyle => this._borderStyle;

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _borderStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderStyle')
  String _borderStyle;

  /** Gets the value of "border-top" */
  String get borderTop => this._borderTop;

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _borderTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTop')
  String _borderTop;

  /** Gets the value of "border-top-color" */
  String get borderTopColor => this._borderTopColor;

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _borderTopColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopColor')
  String _borderTopColor;

  /** Gets the value of "border-top-style" */
  String get borderTopStyle => this._borderTopStyle;

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _borderTopStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopStyle')
  String _borderTopStyle;

  /** Gets the value of "border-top-width" */
  String get borderTopWidth => this._borderTopWidth;

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _borderTopWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopWidth')
  String _borderTopWidth;

  /** Gets the value of "border-width" */
  String get borderWidth => this._borderWidth;

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _borderWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderWidth')
  String _borderWidth;

  /** Gets the value of "bottom" */
  String get bottom => this._bottom;

  /** Sets the value of "bottom" */
  set bottom(String value) {
    _bottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('bottom')
  String _bottom;

  /** Gets the value of "caption-side" */
  String get captionSide => this._captionSide;

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _captionSide = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('captionSide')
  String _captionSide;

  /** Gets the value of "clear" */
  String get clear => this._clear;

  /** Sets the value of "clear" */
  set clear(String value) {
    _clear = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('clear')
  String _clear;

  /** Gets the value of "clip" */
  String get clip => this._clip;

  /** Sets the value of "clip" */
  set clip(String value) {
    _clip = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('clip')
  String _clip;

  /** Gets the value of "color" */
  String get color => this._color;

  /** Sets the value of "color" */
  set color(String value) {
    _color = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('color')
  String _color;

  /** Gets the value of "content" */
  String get content => this._content;

  /** Sets the value of "content" */
  set content(String value) {
    _content = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('content')
  String _content;

  /** Gets the value of "cursor" */
  String get cursor => this._cursor;

  /** Sets the value of "cursor" */
  set cursor(String value) {
    _cursor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('cursor')
  String _cursor;

  /** Gets the value of "direction" */
  String get direction => this._direction;

  /** Sets the value of "direction" */
  set direction(String value) {
    _direction = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('direction')
  String _direction;

  /** Gets the value of "display" */
  String get display => this._display;

  /** Sets the value of "display" */
  set display(String value) {
    _display = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('display')
  String _display;

  /** Gets the value of "empty-cells" */
  String get emptyCells => this._emptyCells;

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _emptyCells = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('emptyCells')
  String _emptyCells;

  /** Gets the value of "font" */
  String get font => this._font;

  /** Sets the value of "font" */
  set font(String value) {
    _font = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('font')
  String _font;

  /** Gets the value of "font-family" */
  String get fontFamily => this._fontFamily;

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _fontFamily = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontFamily')
  String _fontFamily;

  /** Gets the value of "font-size" */
  String get fontSize => this._fontSize;

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _fontSize = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontSize')
  String _fontSize;

  /** Gets the value of "font-style" */
  String get fontStyle => this._fontStyle;

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _fontStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontStyle')
  String _fontStyle;

  /** Gets the value of "font-variant" */
  String get fontVariant => this._fontVariant;

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _fontVariant = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontVariant')
  String _fontVariant;

  /** Gets the value of "font-weight" */
  String get fontWeight => this._fontWeight;

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _fontWeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontWeight')
  String _fontWeight;

  /** Gets the value of "height" */
  String get height => this._height;

  /** Sets the value of "height" */
  set height(String value) {
    _height = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('height')
  String _height;

  /** Gets the value of "left" */
  String get left => this._left;

  /** Sets the value of "left" */
  set left(String value) {
    _left = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('left')
  String _left;

  /** Gets the value of "letter-spacing" */
  String get letterSpacing => this._letterSpacing;

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _letterSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('letterSpacing')
  String _letterSpacing;

  /** Gets the value of "line-height" */
  String get lineHeight => this._lineHeight;

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _lineHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('lineHeight')
  String _lineHeight;

  /** Gets the value of "list-style" */
  String get listStyle => this._listStyle;

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _listStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyle')
  String _listStyle;

  /** Gets the value of "list-style-image" */
  String get listStyleImage => this._listStyleImage;

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _listStyleImage = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyleImage')
  String _listStyleImage;

  /** Gets the value of "list-style-position" */
  String get listStylePosition => this._listStylePosition;

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _listStylePosition = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStylePosition')
  String _listStylePosition;

  /** Gets the value of "list-style-type" */
  String get listStyleType => this._listStyleType;

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _listStyleType = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyleType')
  String _listStyleType;

  /** Gets the value of "margin" */
  String get margin => this._margin;

  /** Sets the value of "margin" */
  set margin(String value) {
    _margin = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('margin')
  String _margin;

  /** Gets the value of "margin-bottom" */
  String get marginBottom => this._marginBottom;

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _marginBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginBottom')
  String _marginBottom;

  /** Gets the value of "margin-left" */
  String get marginLeft => this._marginLeft;

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _marginLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginLeft')
  String _marginLeft;

  /** Gets the value of "margin-right" */
  String get marginRight => this._marginRight;

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _marginRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginRight')
  String _marginRight;

  /** Gets the value of "margin-top" */
  String get marginTop => this._marginTop;

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _marginTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginTop')
  String _marginTop;

  /** Gets the value of "max-height" */
  String get maxHeight => this._maxHeight;

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _maxHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('maxHeight')
  String _maxHeight;

  /** Gets the value of "max-width" */
  String get maxWidth => this._maxWidth;

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _maxWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('maxWidth')
  String _maxWidth;

  /** Gets the value of "min-height" */
  String get minHeight => this._minHeight;

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _minHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('minHeight')
  String _minHeight;

  /** Gets the value of "min-width" */
  String get minWidth => this._minWidth;

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _minWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('minWidth')
  String _minWidth;

  /** Gets the value of "outline" */
  String get outline => this._outline;

  /** Sets the value of "outline" */
  set outline(String value) {
    _outline = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outline')
  String _outline;

  /** Gets the value of "outline-color" */
  String get outlineColor => this._outlineColor;

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _outlineColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineColor')
  String _outlineColor;

  /** Gets the value of "outline-style" */
  String get outlineStyle => this._outlineStyle;

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _outlineStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineStyle')
  String _outlineStyle;

  /** Gets the value of "outline-width" */
  String get outlineWidth => this._outlineWidth;

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _outlineWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineWidth')
  String _outlineWidth;

  /** Gets the value of "overflow" */
  String get overflow => this._overflow;

  /** Sets the value of "overflow" */
  set overflow(String value) {
    _overflow = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('overflow')
  String _overflow;

  /** Gets the value of "padding" */
  String get padding => this._padding;

  /** Sets the value of "padding" */
  set padding(String value) {
    _padding = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('padding')
  String _padding;

  /** Gets the value of "padding-bottom" */
  String get paddingBottom => this._paddingBottom;

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _paddingBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingBottom')
  String _paddingBottom;

  /** Gets the value of "padding-left" */
  String get paddingLeft => this._paddingLeft;

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _paddingLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingLeft')
  String _paddingLeft;

  /** Gets the value of "padding-right" */
  String get paddingRight => this._paddingRight;

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _paddingRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingRight')
  String _paddingRight;

  /** Gets the value of "padding-top" */
  String get paddingTop => this._paddingTop;

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _paddingTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingTop')
  String _paddingTop;

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => this._pageBreakAfter;

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _pageBreakAfter = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakAfter')
  String _pageBreakAfter;

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => this._pageBreakBefore;

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _pageBreakBefore = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakBefore')
  String _pageBreakBefore;

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => this._pageBreakInside;

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _pageBreakInside = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakInside')
  String _pageBreakInside;

  /** Gets the value of "position" */
  String get position => this._position;

  /** Sets the value of "position" */
  set position(String value) {
    _position = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('position')
  String _position;

  /** Gets the value of "quotes" */
  String get quotes => this._quotes;

  /** Sets the value of "quotes" */
  set quotes(String value) {
    _quotes = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('quotes')
  String _quotes;

  /** Gets the value of "right" */
  String get right => this._right;

  /** Sets the value of "right" */
  set right(String value) {
    _right = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('right')
  String _right;

  /** Gets the value of "table-layout" */
  String get tableLayout => this._tableLayout;

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _tableLayout = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('tableLayout')
  String _tableLayout;

  /** Gets the value of "text-align" */
  String get textAlign => this._textAlign;

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _textAlign = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textAlign')
  String _textAlign;

  /** Gets the value of "text-decoration" */
  String get textDecoration => this._textDecoration;

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _textDecoration = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textDecoration')
  String _textDecoration;

  /** Gets the value of "text-indent" */
  String get textIndent => this._textIndent;

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _textIndent = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textIndent')
  String _textIndent;

  /** Gets the value of "text-transform" */
  String get textTransform => this._textTransform;

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _textTransform = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textTransform')
  String _textTransform;

  /** Gets the value of "top" */
  String get top => this._top;

  /** Sets the value of "top" */
  set top(String value) {
    _top = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('top')
  String _top;

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => this._unicodeBidi;

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _unicodeBidi = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('unicodeBidi')
  String _unicodeBidi;

  /** Gets the value of "vertical-align" */
  String get verticalAlign => this._verticalAlign;

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _verticalAlign = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('verticalAlign')
  String _verticalAlign;

  /** Gets the value of "visibility" */
  String get visibility => this._visibility;

  /** Sets the value of "visibility" */
  set visibility(String value) {
    _visibility = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('visibility')
  String _visibility;

  /** Gets the value of "white-space" */
  String get whiteSpace => this._whiteSpace;

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _whiteSpace = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('whiteSpace')
  String _whiteSpace;

  /** Gets the value of "width" */
  String get width => this._width;

  /** Sets the value of "width" */
  set width(String value) {
    _width = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('width')
  String _width;

  /** Gets the value of "word-spacing" */
  String get wordSpacing => this._wordSpacing;

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _wordSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('wordSpacing')
  String _wordSpacing;

  /** Gets the value of "z-index" */
  String get zIndex => this._zIndex;

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    _zIndex = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('zIndex')
  String _zIndex;
}

class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
  final Iterable<Element> _elementIterable;
  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;

  _CssStyleDeclarationSet(this._elementIterable) {
    _elementCssStyleDeclarationSetIterable =
        new List.from(_elementIterable).map((e) => e.style);
  }

  String getPropertyValue(String propertyName) =>
      _elementCssStyleDeclarationSetIterable.first
          .getPropertyValue(propertyName);

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable
        .forEach((e) => e.setProperty(propertyName, value, priority));
  }

  void _setAll(String propertyName, String value) {
    value = value == null ? '' : value;
    for (Element element in _elementIterable) {
      JS('void', '#.style[#] = #', element, propertyName, value);
    }
  }

  /** Sets the value of "background" */
  set background(String value) {
    _setAll('background', value);
  }

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _setAll('backgroundAttachment', value);
  }

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _setAll('backgroundColor', value);
  }

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _setAll('backgroundImage', value);
  }

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _setAll('backgroundPosition', value);
  }

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _setAll('backgroundRepeat', value);
  }

  /** Sets the value of "border" */
  set border(String value) {
    _setAll('border', value);
  }

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _setAll('borderBottom', value);
  }

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _setAll('borderBottomColor', value);
  }

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _setAll('borderBottomStyle', value);
  }

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _setAll('borderBottomWidth', value);
  }

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _setAll('borderCollapse', value);
  }

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _setAll('borderColor', value);
  }

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _setAll('borderLeft', value);
  }

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _setAll('borderLeftColor', value);
  }

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _setAll('borderLeftStyle', value);
  }

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _setAll('borderLeftWidth', value);
  }

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _setAll('borderRight', value);
  }

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _setAll('borderRightColor', value);
  }

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _setAll('borderRightStyle', value);
  }

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _setAll('borderRightWidth', value);
  }

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _setAll('borderSpacing', value);
  }

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _setAll('borderStyle', value);
  }

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _setAll('borderTop', value);
  }

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _setAll('borderTopColor', value);
  }

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _setAll('borderTopStyle', value);
  }

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _setAll('borderTopWidth', value);
  }

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _setAll('borderWidth', value);
  }

  /** Sets the value of "bottom" */
  set bottom(String value) {
    _setAll('bottom', value);
  }

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _setAll('captionSide', value);
  }

  /** Sets the value of "clear" */
  set clear(String value) {
    _setAll('clear', value);
  }

  /** Sets the value of "clip" */
  set clip(String value) {
    _setAll('clip', value);
  }

  /** Sets the value of "color" */
  set color(String value) {
    _setAll('color', value);
  }

  /** Sets the value of "content" */
  set content(String value) {
    _setAll('content', value);
  }

  /** Sets the value of "cursor" */
  set cursor(String value) {
    _setAll('cursor', value);
  }

  /** Sets the value of "direction" */
  set direction(String value) {
    _setAll('direction', value);
  }

  /** Sets the value of "display" */
  set display(String value) {
    _setAll('display', value);
  }

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _setAll('emptyCells', value);
  }

  /** Sets the value of "font" */
  set font(String value) {
    _setAll('font', value);
  }

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _setAll('fontFamily', value);
  }

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _setAll('fontSize', value);
  }

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _setAll('fontStyle', value);
  }

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _setAll('fontVariant', value);
  }

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _setAll('fontWeight', value);
  }

  /** Sets the value of "height" */
  set height(String value) {
    _setAll('height', value);
  }

  /** Sets the value of "left" */
  set left(String value) {
    _setAll('left', value);
  }

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _setAll('letterSpacing', value);
  }

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _setAll('lineHeight', value);
  }

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _setAll('listStyle', value);
  }

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _setAll('listStyleImage', value);
  }

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _setAll('listStylePosition', value);
  }

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _setAll('listStyleType', value);
  }

  /** Sets the value of "margin" */
  set margin(String value) {
    _setAll('margin', value);
  }

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _setAll('marginBottom', value);
  }

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _setAll('marginLeft', value);
  }

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _setAll('marginRight', value);
  }

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _setAll('marginTop', value);
  }

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _setAll('maxHeight', value);
  }

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _setAll('maxWidth', value);
  }

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _setAll('minHeight', value);
  }

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _setAll('minWidth', value);
  }

  /** Sets the value of "outline" */
  set outline(String value) {
    _setAll('outline', value);
  }

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _setAll('outlineColor', value);
  }

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _setAll('outlineStyle', value);
  }

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _setAll('outlineWidth', value);
  }

  /** Sets the value of "overflow" */
  set overflow(String value) {
    _setAll('overflow', value);
  }

  /** Sets the value of "padding" */
  set padding(String value) {
    _setAll('padding', value);
  }

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _setAll('paddingBottom', value);
  }

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _setAll('paddingLeft', value);
  }

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _setAll('paddingRight', value);
  }

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _setAll('paddingTop', value);
  }

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _setAll('pageBreakAfter', value);
  }

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _setAll('pageBreakBefore', value);
  }

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _setAll('pageBreakInside', value);
  }

  /** Sets the value of "position" */
  set position(String value) {
    _setAll('position', value);
  }

  /** Sets the value of "quotes" */
  set quotes(String value) {
    _setAll('quotes', value);
  }

  /** Sets the value of "right" */
  set right(String value) {
    _setAll('right', value);
  }

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _setAll('tableLayout', value);
  }

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _setAll('textAlign', value);
  }

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _setAll('textDecoration', value);
  }

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _setAll('textIndent', value);
  }

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _setAll('textTransform', value);
  }

  /** Sets the value of "top" */
  set top(String value) {
    _setAll('top', value);
  }

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _setAll('unicodeBidi', value);
  }

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _setAll('verticalAlign', value);
  }

  /** Sets the value of "visibility" */
  set visibility(String value) {
    _setAll('visibility', value);
  }

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _setAll('whiteSpace', value);
  }

  /** Sets the value of "width" */
  set width(String value) {
    _setAll('width', value);
  }

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _setAll('wordSpacing', value);
  }

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    _setAll('zIndex', value);
  }

  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

abstract class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName);
  void setProperty(String propertyName, String value, [String priority]);

  /** Gets the value of "align-content" */
  String get alignContent => getPropertyValue('align-content');

  /** Sets the value of "align-content" */
  set alignContent(String value) {
    setProperty('align-content', value, '');
  }

  /** Gets the value of "align-items" */
  String get alignItems => getPropertyValue('align-items');

  /** Sets the value of "align-items" */
  set alignItems(String value) {
    setProperty('align-items', value, '');
  }

  /** Gets the value of "align-self" */
  String get alignSelf => getPropertyValue('align-self');

  /** Sets the value of "align-self" */
  set alignSelf(String value) {
    setProperty('align-self', value, '');
  }

  /** Gets the value of "animation" */
  String get animation => getPropertyValue('animation');

  /** Sets the value of "animation" */
  set animation(String value) {
    setProperty('animation', value, '');
  }

  /** Gets the value of "animation-delay" */
  String get animationDelay => getPropertyValue('animation-delay');

  /** Sets the value of "animation-delay" */
  set animationDelay(String value) {
    setProperty('animation-delay', value, '');
  }

  /** Gets the value of "animation-direction" */
  String get animationDirection => getPropertyValue('animation-direction');

  /** Sets the value of "animation-direction" */
  set animationDirection(String value) {
    setProperty('animation-direction', value, '');
  }

  /** Gets the value of "animation-duration" */
  String get animationDuration => getPropertyValue('animation-duration');

  /** Sets the value of "animation-duration" */
  set animationDuration(String value) {
    setProperty('animation-duration', value, '');
  }

  /** Gets the value of "animation-fill-mode" */
  String get animationFillMode => getPropertyValue('animation-fill-mode');

  /** Sets the value of "animation-fill-mode" */
  set animationFillMode(String value) {
    setProperty('animation-fill-mode', value, '');
  }

  /** Gets the value of "animation-iteration-count" */
  String get animationIterationCount =>
      getPropertyValue('animation-iteration-count');

  /** Sets the value of "animation-iteration-count" */
  set animationIterationCount(String value) {
    setProperty('animation-iteration-count', value, '');
  }

  /** Gets the value of "animation-name" */
  String get animationName => getPropertyValue('animation-name');

  /** Sets the value of "animation-name" */
  set animationName(String value) {
    setProperty('animation-name', value, '');
  }

  /** Gets the value of "animation-play-state" */
  String get animationPlayState => getPropertyValue('animation-play-state');

  /** Sets the value of "animation-play-state" */
  set animationPlayState(String value) {
    setProperty('animation-play-state', value, '');
  }

  /** Gets the value of "animation-timing-function" */
  String get animationTimingFunction =>
      getPropertyValue('animation-timing-function');

  /** Sets the value of "animation-timing-function" */
  set animationTimingFunction(String value) {
    setProperty('animation-timing-function', value, '');
  }

  /** Gets the value of "app-region" */
  String get appRegion => getPropertyValue('app-region');

  /** Sets the value of "app-region" */
  set appRegion(String value) {
    setProperty('app-region', value, '');
  }

  /** Gets the value of "appearance" */
  String get appearance => getPropertyValue('appearance');

  /** Sets the value of "appearance" */
  set appearance(String value) {
    setProperty('appearance', value, '');
  }

  /** Gets the value of "aspect-ratio" */
  String get aspectRatio => getPropertyValue('aspect-ratio');

  /** Sets the value of "aspect-ratio" */
  set aspectRatio(String value) {
    setProperty('aspect-ratio', value, '');
  }

  /** Gets the value of "backface-visibility" */
  String get backfaceVisibility => getPropertyValue('backface-visibility');

  /** Sets the value of "backface-visibility" */
  set backfaceVisibility(String value) {
    setProperty('backface-visibility', value, '');
  }

  /** Gets the value of "background" */
  String get background => getPropertyValue('background');

  /** Sets the value of "background" */
  set background(String value) {
    setProperty('background', value, '');
  }

  /** Gets the value of "background-attachment" */
  String get backgroundAttachment => getPropertyValue('background-attachment');

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    setProperty('background-attachment', value, '');
  }

  /** Gets the value of "background-blend-mode" */
  String get backgroundBlendMode => getPropertyValue('background-blend-mode');

  /** Sets the value of "background-blend-mode" */
  set backgroundBlendMode(String value) {
    setProperty('background-blend-mode', value, '');
  }

  /** Gets the value of "background-clip" */
  String get backgroundClip => getPropertyValue('background-clip');

  /** Sets the value of "background-clip" */
  set backgroundClip(String value) {
    setProperty('background-clip', value, '');
  }

  /** Gets the value of "background-color" */
  String get backgroundColor => getPropertyValue('background-color');

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    setProperty('background-color', value, '');
  }

  /** Gets the value of "background-composite" */
  String get backgroundComposite => getPropertyValue('background-composite');

  /** Sets the value of "background-composite" */
  set backgroundComposite(String value) {
    setProperty('background-composite', value, '');
  }

  /** Gets the value of "background-image" */
  String get backgroundImage => getPropertyValue('background-image');

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    setProperty('background-image', value, '');
  }

  /** Gets the value of "background-origin" */
  String get backgroundOrigin => getPropertyValue('background-origin');

  /** Sets the value of "background-origin" */
  set backgroundOrigin(String value) {
    setProperty('background-origin', value, '');
  }

  /** Gets the value of "background-position" */
  String get backgroundPosition => getPropertyValue('background-position');

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    setProperty('background-position', value, '');
  }

  /** Gets the value of "background-position-x" */
  String get backgroundPositionX => getPropertyValue('background-position-x');

  /** Sets the value of "background-position-x" */
  set backgroundPositionX(String value) {
    setProperty('background-position-x', value, '');
  }

  /** Gets the value of "background-position-y" */
  String get backgroundPositionY => getPropertyValue('background-position-y');

  /** Sets the value of "background-position-y" */
  set backgroundPositionY(String value) {
    setProperty('background-position-y', value, '');
  }

  /** Gets the value of "background-repeat" */
  String get backgroundRepeat => getPropertyValue('background-repeat');

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    setProperty('background-repeat', value, '');
  }

  /** Gets the value of "background-repeat-x" */
  String get backgroundRepeatX => getPropertyValue('background-repeat-x');

  /** Sets the value of "background-repeat-x" */
  set backgroundRepeatX(String value) {
    setProperty('background-repeat-x', value, '');
  }

  /** Gets the value of "background-repeat-y" */
  String get backgroundRepeatY => getPropertyValue('background-repeat-y');

  /** Sets the value of "background-repeat-y" */
  set backgroundRepeatY(String value) {
    setProperty('background-repeat-y', value, '');
  }

  /** Gets the value of "background-size" */
  String get backgroundSize => getPropertyValue('background-size');

  /** Sets the value of "background-size" */
  set backgroundSize(String value) {
    setProperty('background-size', value, '');
  }

  /** Gets the value of "border" */
  String get border => getPropertyValue('border');

  /** Sets the value of "border" */
  set border(String value) {
    setProperty('border', value, '');
  }

  /** Gets the value of "border-after" */
  String get borderAfter => getPropertyValue('border-after');

  /** Sets the value of "border-after" */
  set borderAfter(String value) {
    setProperty('border-after', value, '');
  }

  /** Gets the value of "border-after-color" */
  String get borderAfterColor => getPropertyValue('border-after-color');

  /** Sets the value of "border-after-color" */
  set borderAfterColor(String value) {
    setProperty('border-after-color', value, '');
  }

  /** Gets the value of "border-after-style" */
  String get borderAfterStyle => getPropertyValue('border-after-style');

  /** Sets the value of "border-after-style" */
  set borderAfterStyle(String value) {
    setProperty('border-after-style', value, '');
  }

  /** Gets the value of "border-after-width" */
  String get borderAfterWidth => getPropertyValue('border-after-width');

  /** Sets the value of "border-after-width" */
  set borderAfterWidth(String value) {
    setProperty('border-after-width', value, '');
  }

  /** Gets the value of "border-before" */
  String get borderBefore => getPropertyValue('border-before');

  /** Sets the value of "border-before" */
  set borderBefore(String value) {
    setProperty('border-before', value, '');
  }

  /** Gets the value of "border-before-color" */
  String get borderBeforeColor => getPropertyValue('border-before-color');

  /** Sets the value of "border-before-color" */
  set borderBeforeColor(String value) {
    setProperty('border-before-color', value, '');
  }

  /** Gets the value of "border-before-style" */
  String get borderBeforeStyle => getPropertyValue('border-before-style');

  /** Sets the value of "border-before-style" */
  set borderBeforeStyle(String value) {
    setProperty('border-before-style', value, '');
  }

  /** Gets the value of "border-before-width" */
  String get borderBeforeWidth => getPropertyValue('border-before-width');

  /** Sets the value of "border-before-width" */
  set borderBeforeWidth(String value) {
    setProperty('border-before-width', value, '');
  }

  /** Gets the value of "border-bottom" */
  String get borderBottom => getPropertyValue('border-bottom');

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    setProperty('border-bottom', value, '');
  }

  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor => getPropertyValue('border-bottom-color');

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    setProperty('border-bottom-color', value, '');
  }

  /** Gets the value of "border-bottom-left-radius" */
  String get borderBottomLeftRadius =>
      getPropertyValue('border-bottom-left-radius');

  /** Sets the value of "border-bottom-left-radius" */
  set borderBottomLeftRadius(String value) {
    setProperty('border-bottom-left-radius', value, '');
  }

  /** Gets the value of "border-bottom-right-radius" */
  String get borderBottomRightRadius =>
      getPropertyValue('border-bottom-right-radius');

  /** Sets the value of "border-bottom-right-radius" */
  set borderBottomRightRadius(String value) {
    setProperty('border-bottom-right-radius', value, '');
  }

  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle => getPropertyValue('border-bottom-style');

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    setProperty('border-bottom-style', value, '');
  }

  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth => getPropertyValue('border-bottom-width');

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    setProperty('border-bottom-width', value, '');
  }

  /** Gets the value of "border-collapse" */
  String get borderCollapse => getPropertyValue('border-collapse');

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    setProperty('border-collapse', value, '');
  }

  /** Gets the value of "border-color" */
  String get borderColor => getPropertyValue('border-color');

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    setProperty('border-color', value, '');
  }

  /** Gets the value of "border-end" */
  String get borderEnd => getPropertyValue('border-end');

  /** Sets the value of "border-end" */
  set borderEnd(String value) {
    setProperty('border-end', value, '');
  }

  /** Gets the value of "border-end-color" */
  String get borderEndColor => getPropertyValue('border-end-color');

  /** Sets the value of "border-end-color" */
  set borderEndColor(String value) {
    setProperty('border-end-color', value, '');
  }

  /** Gets the value of "border-end-style" */
  String get borderEndStyle => getPropertyValue('border-end-style');

  /** Sets the value of "border-end-style" */
  set borderEndStyle(String value) {
    setProperty('border-end-style', value, '');
  }

  /** Gets the value of "border-end-width" */
  String get borderEndWidth => getPropertyValue('border-end-width');

  /** Sets the value of "border-end-width" */
  set borderEndWidth(String value) {
    setProperty('border-end-width', value, '');
  }

  /** Gets the value of "border-fit" */
  String get borderFit => getPropertyValue('border-fit');

  /** Sets the value of "border-fit" */
  set borderFit(String value) {
    setProperty('border-fit', value, '');
  }

  /** Gets the value of "border-horizontal-spacing" */
  String get borderHorizontalSpacing =>
      getPropertyValue('border-horizontal-spacing');

  /** Sets the value of "border-horizontal-spacing" */
  set borderHorizontalSpacing(String value) {
    setProperty('border-horizontal-spacing', value, '');
  }

  /** Gets the value of "border-image" */
  String get borderImage => getPropertyValue('border-image');

  /** Sets the value of "border-image" */
  set borderImage(String value) {
    setProperty('border-image', value, '');
  }

  /** Gets the value of "border-image-outset" */
  String get borderImageOutset => getPropertyValue('border-image-outset');

  /** Sets the value of "border-image-outset" */
  set borderImageOutset(String value) {
    setProperty('border-image-outset', value, '');
  }

  /** Gets the value of "border-image-repeat" */
  String get borderImageRepeat => getPropertyValue('border-image-repeat');

  /** Sets the value of "border-image-repeat" */
  set borderImageRepeat(String value) {
    setProperty('border-image-repeat', value, '');
  }

  /** Gets the value of "border-image-slice" */
  String get borderImageSlice => getPropertyValue('border-image-slice');

  /** Sets the value of "border-image-slice" */
  set borderImageSlice(String value) {
    setProperty('border-image-slice', value, '');
  }

  /** Gets the value of "border-image-source" */
  String get borderImageSource => getPropertyValue('border-image-source');

  /** Sets the value of "border-image-source" */
  set borderImageSource(String value) {
    setProperty('border-image-source', value, '');
  }

  /** Gets the value of "border-image-width" */
  String get borderImageWidth => getPropertyValue('border-image-width');

  /** Sets the value of "border-image-width" */
  set borderImageWidth(String value) {
    setProperty('border-image-width', value, '');
  }

  /** Gets the value of "border-left" */
  String get borderLeft => getPropertyValue('border-left');

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    setProperty('border-left', value, '');
  }

  /** Gets the value of "border-left-color" */
  String get borderLeftColor => getPropertyValue('border-left-color');

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    setProperty('border-left-color', value, '');
  }

  /** Gets the value of "border-left-style" */
  String get borderLeftStyle => getPropertyValue('border-left-style');

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    setProperty('border-left-style', value, '');
  }

  /** Gets the value of "border-left-width" */
  String get borderLeftWidth => getPropertyValue('border-left-width');

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    setProperty('border-left-width', value, '');
  }

  /** Gets the value of "border-radius" */
  String get borderRadius => getPropertyValue('border-radius');

  /** Sets the value of "border-radius" */
  set borderRadius(String value) {
    setProperty('border-radius', value, '');
  }

  /** Gets the value of "border-right" */
  String get borderRight => getPropertyValue('border-right');

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    setProperty('border-right', value, '');
  }

  /** Gets the value of "border-right-color" */
  String get borderRightColor => getPropertyValue('border-right-color');

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    setProperty('border-right-color', value, '');
  }

  /** Gets the value of "border-right-style" */
  String get borderRightStyle => getPropertyValue('border-right-style');

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    setProperty('border-right-style', value, '');
  }

  /** Gets the value of "border-right-width" */
  String get borderRightWidth => getPropertyValue('border-right-width');

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    setProperty('border-right-width', value, '');
  }

  /** Gets the value of "border-spacing" */
  String get borderSpacing => getPropertyValue('border-spacing');

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    setProperty('border-spacing', value, '');
  }

  /** Gets the value of "border-start" */
  String get borderStart => getPropertyValue('border-start');

  /** Sets the value of "border-start" */
  set borderStart(String value) {
    setProperty('border-start', value, '');
  }

  /** Gets the value of "border-start-color" */
  String get borderStartColor => getPropertyValue('border-start-color');

  /** Sets the value of "border-start-color" */
  set borderStartColor(String value) {
    setProperty('border-start-color', value, '');
  }

  /** Gets the value of "border-start-style" */
  String get borderStartStyle => getPropertyValue('border-start-style');

  /** Sets the value of "border-start-style" */
  set borderStartStyle(String value) {
    setProperty('border-start-style', value, '');
  }

  /** Gets the value of "border-start-width" */
  String get borderStartWidth => getPropertyValue('border-start-width');

  /** Sets the value of "border-start-width" */
  set borderStartWidth(String value) {
    setProperty('border-start-width', value, '');
  }

  /** Gets the value of "border-style" */
  String get borderStyle => getPropertyValue('border-style');

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    setProperty('border-style', value, '');
  }

  /** Gets the value of "border-top" */
  String get borderTop => getPropertyValue('border-top');

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    setProperty('border-top', value, '');
  }

  /** Gets the value of "border-top-color" */
  String get borderTopColor => getPropertyValue('border-top-color');

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    setProperty('border-top-color', value, '');
  }

  /** Gets the value of "border-top-left-radius" */
  String get borderTopLeftRadius => getPropertyValue('border-top-left-radius');

  /** Sets the value of "border-top-left-radius" */
  set borderTopLeftRadius(String value) {
    setProperty('border-top-left-radius', value, '');
  }

  /** Gets the value of "border-top-right-radius" */
  String get borderTopRightRadius =>
      getPropertyValue('border-top-right-radius');

  /** Sets the value of "border-top-right-radius" */
  set borderTopRightRadius(String value) {
    setProperty('border-top-right-radius', value, '');
  }

  /** Gets the value of "border-top-style" */
  String get borderTopStyle => getPropertyValue('border-top-style');

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    setProperty('border-top-style', value, '');
  }

  /** Gets the value of "border-top-width" */
  String get borderTopWidth => getPropertyValue('border-top-width');

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    setProperty('border-top-width', value, '');
  }

  /** Gets the value of "border-vertical-spacing" */
  String get borderVerticalSpacing =>
      getPropertyValue('border-vertical-spacing');

  /** Sets the value of "border-vertical-spacing" */
  set borderVerticalSpacing(String value) {
    setProperty('border-vertical-spacing', value, '');
  }

  /** Gets the value of "border-width" */
  String get borderWidth => getPropertyValue('border-width');

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    setProperty('border-width', value, '');
  }

  /** Gets the value of "bottom" */
  String get bottom => getPropertyValue('bottom');

  /** Sets the value of "bottom" */
  set bottom(String value) {
    setProperty('bottom', value, '');
  }

  /** Gets the value of "box-align" */
  String get boxAlign => getPropertyValue('box-align');

  /** Sets the value of "box-align" */
  set boxAlign(String value) {
    setProperty('box-align', value, '');
  }

  /** Gets the value of "box-decoration-break" */
  String get boxDecorationBreak => getPropertyValue('box-decoration-break');

  /** Sets the value of "box-decoration-break" */
  set boxDecorationBreak(String value) {
    setProperty('box-decoration-break', value, '');
  }

  /** Gets the value of "box-direction" */
  String get boxDirection => getPropertyValue('box-direction');

  /** Sets the value of "box-direction" */
  set boxDirection(String value) {
    setProperty('box-direction', value, '');
  }

  /** Gets the value of "box-flex" */
  String get boxFlex => getPropertyValue('box-flex');

  /** Sets the value of "box-flex" */
  set boxFlex(String value) {
    setProperty('box-flex', value, '');
  }

  /** Gets the value of "box-flex-group" */
  String get boxFlexGroup => getPropertyValue('box-flex-group');

  /** Sets the value of "box-flex-group" */
  set boxFlexGroup(String value) {
    setProperty('box-flex-group', value, '');
  }

  /** Gets the value of "box-lines" */
  String get boxLines => getPropertyValue('box-lines');

  /** Sets the value of "box-lines" */
  set boxLines(String value) {
    setProperty('box-lines', value, '');
  }

  /** Gets the value of "box-ordinal-group" */
  String get boxOrdinalGroup => getPropertyValue('box-ordinal-group');

  /** Sets the value of "box-ordinal-group" */
  set boxOrdinalGroup(String value) {
    setProperty('box-ordinal-group', value, '');
  }

  /** Gets the value of "box-orient" */
  String get boxOrient => getPropertyValue('box-orient');

  /** Sets the value of "box-orient" */
  set boxOrient(String value) {
    setProperty('box-orient', value, '');
  }

  /** Gets the value of "box-pack" */
  String get boxPack => getPropertyValue('box-pack');

  /** Sets the value of "box-pack" */
  set boxPack(String value) {
    setProperty('box-pack', value, '');
  }

  /** Gets the value of "box-reflect" */
  String get boxReflect => getPropertyValue('box-reflect');

  /** Sets the value of "box-reflect" */
  set boxReflect(String value) {
    setProperty('box-reflect', value, '');
  }

  /** Gets the value of "box-shadow" */
  String get boxShadow => getPropertyValue('box-shadow');

  /** Sets the value of "box-shadow" */
  set boxShadow(String value) {
    setProperty('box-shadow', value, '');
  }

  /** Gets the value of "box-sizing" */
  String get boxSizing => getPropertyValue('box-sizing');

  /** Sets the value of "box-sizing" */
  set boxSizing(String value) {
    setProperty('box-sizing', value, '');
  }

  /** Gets the value of "caption-side" */
  String get captionSide => getPropertyValue('caption-side');

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    setProperty('caption-side', value, '');
  }

  /** Gets the value of "clear" */
  String get clear => getPropertyValue('clear');

  /** Sets the value of "clear" */
  set clear(String value) {
    setProperty('clear', value, '');
  }

  /** Gets the value of "clip" */
  String get clip => getPropertyValue('clip');

  /** Sets the value of "clip" */
  set clip(String value) {
    setProperty('clip', value, '');
  }

  /** Gets the value of "clip-path" */
  String get clipPath => getPropertyValue('clip-path');

  /** Sets the value of "clip-path" */
  set clipPath(String value) {
    setProperty('clip-path', value, '');
  }

  /** Gets the value of "color" */
  String get color => getPropertyValue('color');

  /** Sets the value of "color" */
  set color(String value) {
    setProperty('color', value, '');
  }

  /** Gets the value of "column-break-after" */
  String get columnBreakAfter => getPropertyValue('column-break-after');

  /** Sets the value of "column-break-after" */
  set columnBreakAfter(String value) {
    setProperty('column-break-after', value, '');
  }

  /** Gets the value of "column-break-before" */
  String get columnBreakBefore => getPropertyValue('column-break-before');

  /** Sets the value of "column-break-before" */
  set columnBreakBefore(String value) {
    setProperty('column-break-before', value, '');
  }

  /** Gets the value of "column-break-inside" */
  String get columnBreakInside => getPropertyValue('column-break-inside');

  /** Sets the value of "column-break-inside" */
  set columnBreakInside(String value) {
    setProperty('column-break-inside', value, '');
  }

  /** Gets the value of "column-count" */
  String get columnCount => getPropertyValue('column-count');

  /** Sets the value of "column-count" */
  set columnCount(String value) {
    setProperty('column-count', value, '');
  }

  /** Gets the value of "column-fill" */
  String get columnFill => getPropertyValue('column-fill');

  /** Sets the value of "column-fill" */
  set columnFill(String value) {
    setProperty('column-fill', value, '');
  }

  /** Gets the value of "column-gap" */
  String get columnGap => getPropertyValue('column-gap');

  /** Sets the value of "column-gap" */
  set columnGap(String value) {
    setProperty('column-gap', value, '');
  }

  /** Gets the value of "column-rule" */
  String get columnRule => getPropertyValue('column-rule');

  /** Sets the value of "column-rule" */
  set columnRule(String value) {
    setProperty('column-rule', value, '');
  }

  /** Gets the value of "column-rule-color" */
  String get columnRuleColor => getPropertyValue('column-rule-color');

  /** Sets the value of "column-rule-color" */
  set columnRuleColor(String value) {
    setProperty('column-rule-color', value, '');
  }

  /** Gets the value of "column-rule-style" */
  String get columnRuleStyle => getPropertyValue('column-rule-style');

  /** Sets the value of "column-rule-style" */
  set columnRuleStyle(String value) {
    setProperty('column-rule-style', value, '');
  }

  /** Gets the value of "column-rule-width" */
  String get columnRuleWidth => getPropertyValue('column-rule-width');

  /** Sets the value of "column-rule-width" */
  set columnRuleWidth(String value) {
    setProperty('column-rule-width', value, '');
  }

  /** Gets the value of "column-span" */
  String get columnSpan => getPropertyValue('column-span');

  /** Sets the value of "column-span" */
  set columnSpan(String value) {
    setProperty('column-span', value, '');
  }

  /** Gets the value of "column-width" */
  String get columnWidth => getPropertyValue('column-width');

  /** Sets the value of "column-width" */
  set columnWidth(String value) {
    setProperty('column-width', value, '');
  }

  /** Gets the value of "columns" */
  String get columns => getPropertyValue('columns');

  /** Sets the value of "columns" */
  set columns(String value) {
    setProperty('columns', value, '');
  }

  /** Gets the value of "content" */
  String get content => getPropertyValue('content');

  /** Sets the value of "content" */
  set content(String value) {
    setProperty('content', value, '');
  }

  /** Gets the value of "counter-increment" */
  String get counterIncrement => getPropertyValue('counter-increment');

  /** Sets the value of "counter-increment" */
  set counterIncrement(String value) {
    setProperty('counter-increment', value, '');
  }

  /** Gets the value of "counter-reset" */
  String get counterReset => getPropertyValue('counter-reset');

  /** Sets the value of "counter-reset" */
  set counterReset(String value) {
    setProperty('counter-reset', value, '');
  }

  /** Gets the value of "cursor" */
  String get cursor => getPropertyValue('cursor');

  /** Sets the value of "cursor" */
  set cursor(String value) {
    setProperty('cursor', value, '');
  }

  /** Gets the value of "direction" */
  String get direction => getPropertyValue('direction');

  /** Sets the value of "direction" */
  set direction(String value) {
    setProperty('direction', value, '');
  }

  /** Gets the value of "display" */
  String get display => getPropertyValue('display');

  /** Sets the value of "display" */
  set display(String value) {
    setProperty('display', value, '');
  }

  /** Gets the value of "empty-cells" */
  String get emptyCells => getPropertyValue('empty-cells');

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    setProperty('empty-cells', value, '');
  }

  /** Gets the value of "filter" */
  String get filter => getPropertyValue('filter');

  /** Sets the value of "filter" */
  set filter(String value) {
    setProperty('filter', value, '');
  }

  /** Gets the value of "flex" */
  String get flex => getPropertyValue('flex');

  /** Sets the value of "flex" */
  set flex(String value) {
    setProperty('flex', value, '');
  }

  /** Gets the value of "flex-basis" */
  String get flexBasis => getPropertyValue('flex-basis');

  /** Sets the value of "flex-basis" */
  set flexBasis(String value) {
    setProperty('flex-basis', value, '');
  }

  /** Gets the value of "flex-direction" */
  String get flexDirection => getPropertyValue('flex-direction');

  /** Sets the value of "flex-direction" */
  set flexDirection(String value) {
    setProperty('flex-direction', value, '');
  }

  /** Gets the value of "flex-flow" */
  String get flexFlow => getPropertyValue('flex-flow');

  /** Sets the value of "flex-flow" */
  set flexFlow(String value) {
    setProperty('flex-flow', value, '');
  }

  /** Gets the value of "flex-grow" */
  String get flexGrow => getPropertyValue('flex-grow');

  /** Sets the value of "flex-grow" */
  set flexGrow(String value) {
    setProperty('flex-grow', value, '');
  }

  /** Gets the value of "flex-shrink" */
  String get flexShrink => getPropertyValue('flex-shrink');

  /** Sets the value of "flex-shrink" */
  set flexShrink(String value) {
    setProperty('flex-shrink', value, '');
  }

  /** Gets the value of "flex-wrap" */
  String get flexWrap => getPropertyValue('flex-wrap');

  /** Sets the value of "flex-wrap" */
  set flexWrap(String value) {
    setProperty('flex-wrap', value, '');
  }

  /** Gets the value of "float" */
  String get float => getPropertyValue('float');

  /** Sets the value of "float" */
  set float(String value) {
    setProperty('float', value, '');
  }

  /** Gets the value of "font" */
  String get font => getPropertyValue('font');

  /** Sets the value of "font" */
  set font(String value) {
    setProperty('font', value, '');
  }

  /** Gets the value of "font-family" */
  String get fontFamily => getPropertyValue('font-family');

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    setProperty('font-family', value, '');
  }

  /** Gets the value of "font-feature-settings" */
  String get fontFeatureSettings => getPropertyValue('font-feature-settings');

  /** Sets the value of "font-feature-settings" */
  set fontFeatureSettings(String value) {
    setProperty('font-feature-settings', value, '');
  }

  /** Gets the value of "font-kerning" */
  String get fontKerning => getPropertyValue('font-kerning');

  /** Sets the value of "font-kerning" */
  set fontKerning(String value) {
    setProperty('font-kerning', value, '');
  }

  /** Gets the value of "font-size" */
  String get fontSize => getPropertyValue('font-size');

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    setProperty('font-size', value, '');
  }

  /** Gets the value of "font-size-delta" */
  String get fontSizeDelta => getPropertyValue('font-size-delta');

  /** Sets the value of "font-size-delta" */
  set fontSizeDelta(String value) {
    setProperty('font-size-delta', value, '');
  }

  /** Gets the value of "font-smoothing" */
  String get fontSmoothing => getPropertyValue('font-smoothing');

  /** Sets the value of "font-smoothing" */
  set fontSmoothing(String value) {
    setProperty('font-smoothing', value, '');
  }

  /** Gets the value of "font-stretch" */
  String get fontStretch => getPropertyValue('font-stretch');

  /** Sets the value of "font-stretch" */
  set fontStretch(String value) {
    setProperty('font-stretch', value, '');
  }

  /** Gets the value of "font-style" */
  String get fontStyle => getPropertyValue('font-style');

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    setProperty('font-style', value, '');
  }

  /** Gets the value of "font-variant" */
  String get fontVariant => getPropertyValue('font-variant');

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    setProperty('font-variant', value, '');
  }

  /** Gets the value of "font-variant-ligatures" */
  String get fontVariantLigatures => getPropertyValue('font-variant-ligatures');

  /** Sets the value of "font-variant-ligatures" */
  set fontVariantLigatures(String value) {
    setProperty('font-variant-ligatures', value, '');
  }

  /** Gets the value of "font-weight" */
  String get fontWeight => getPropertyValue('font-weight');

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    setProperty('font-weight', value, '');
  }

  /** Gets the value of "grid" */
  String get grid => getPropertyValue('grid');

  /** Sets the value of "grid" */
  set grid(String value) {
    setProperty('grid', value, '');
  }

  /** Gets the value of "grid-area" */
  String get gridArea => getPropertyValue('grid-area');

  /** Sets the value of "grid-area" */
  set gridArea(String value) {
    setProperty('grid-area', value, '');
  }

  /** Gets the value of "grid-auto-columns" */
  String get gridAutoColumns => getPropertyValue('grid-auto-columns');

  /** Sets the value of "grid-auto-columns" */
  set gridAutoColumns(String value) {
    setProperty('grid-auto-columns', value, '');
  }

  /** Gets the value of "grid-auto-flow" */
  String get gridAutoFlow => getPropertyValue('grid-auto-flow');

  /** Sets the value of "grid-auto-flow" */
  set gridAutoFlow(String value) {
    setProperty('grid-auto-flow', value, '');
  }

  /** Gets the value of "grid-auto-rows" */
  String get gridAutoRows => getPropertyValue('grid-auto-rows');

  /** Sets the value of "grid-auto-rows" */
  set gridAutoRows(String value) {
    setProperty('grid-auto-rows', value, '');
  }

  /** Gets the value of "grid-column" */
  String get gridColumn => getPropertyValue('grid-column');

  /** Sets the value of "grid-column" */
  set gridColumn(String value) {
    setProperty('grid-column', value, '');
  }

  /** Gets the value of "grid-column-end" */
  String get gridColumnEnd => getPropertyValue('grid-column-end');

  /** Sets the value of "grid-column-end" */
  set gridColumnEnd(String value) {
    setProperty('grid-column-end', value, '');
  }

  /** Gets the value of "grid-column-start" */
  String get gridColumnStart => getPropertyValue('grid-column-start');

  /** Sets the value of "grid-column-start" */
  set gridColumnStart(String value) {
    setProperty('grid-column-start', value, '');
  }

  /** Gets the value of "grid-row" */
  String get gridRow => getPropertyValue('grid-row');

  /** Sets the value of "grid-row" */
  set gridRow(String value) {
    setProperty('grid-row', value, '');
  }

  /** Gets the value of "grid-row-end" */
  String get gridRowEnd => getPropertyValue('grid-row-end');

  /** Sets the value of "grid-row-end" */
  set gridRowEnd(String value) {
    setProperty('grid-row-end', value, '');
  }

  /** Gets the value of "grid-row-start" */
  String get gridRowStart => getPropertyValue('grid-row-start');

  /** Sets the value of "grid-row-start" */
  set gridRowStart(String value) {
    setProperty('grid-row-start', value, '');
  }

  /** Gets the value of "grid-template" */
  String get gridTemplate => getPropertyValue('grid-template');

  /** Sets the value of "grid-template" */
  set gridTemplate(String value) {
    setProperty('grid-template', value, '');
  }

  /** Gets the value of "grid-template-areas" */
  String get gridTemplateAreas => getPropertyValue('grid-template-areas');

  /** Sets the value of "grid-template-areas" */
  set gridTemplateAreas(String value) {
    setProperty('grid-template-areas', value, '');
  }

  /** Gets the value of "grid-template-columns" */
  String get gridTemplateColumns => getPropertyValue('grid-template-columns');

  /** Sets the value of "grid-template-columns" */
  set gridTemplateColumns(String value) {
    setProperty('grid-template-columns', value, '');
  }

  /** Gets the value of "grid-template-rows" */
  String get gridTemplateRows => getPropertyValue('grid-template-rows');

  /** Sets the value of "grid-template-rows" */
  set gridTemplateRows(String value) {
    setProperty('grid-template-rows', value, '');
  }

  /** Gets the value of "height" */
  String get height => getPropertyValue('height');

  /** Sets the value of "height" */
  set height(String value) {
    setProperty('height', value, '');
  }

  /** Gets the value of "highlight" */
  String get highlight => getPropertyValue('highlight');

  /** Sets the value of "highlight" */
  set highlight(String value) {
    setProperty('highlight', value, '');
  }

  /** Gets the value of "hyphenate-character" */
  String get hyphenateCharacter => getPropertyValue('hyphenate-character');

  /** Sets the value of "hyphenate-character" */
  set hyphenateCharacter(String value) {
    setProperty('hyphenate-character', value, '');
  }

  /** Gets the value of "image-rendering" */
  String get imageRendering => getPropertyValue('image-rendering');

  /** Sets the value of "image-rendering" */
  set imageRendering(String value) {
    setProperty('image-rendering', value, '');
  }

  /** Gets the value of "isolation" */
  String get isolation => getPropertyValue('isolation');

  /** Sets the value of "isolation" */
  set isolation(String value) {
    setProperty('isolation', value, '');
  }

  /** Gets the value of "justify-content" */
  String get justifyContent => getPropertyValue('justify-content');

  /** Sets the value of "justify-content" */
  set justifyContent(String value) {
    setProperty('justify-content', value, '');
  }

  /** Gets the value of "justify-self" */
  String get justifySelf => getPropertyValue('justify-self');

  /** Sets the value of "justify-self" */
  set justifySelf(String value) {
    setProperty('justify-self', value, '');
  }

  /** Gets the value of "left" */
  String get left => getPropertyValue('left');

  /** Sets the value of "left" */
  set left(String value) {
    setProperty('left', value, '');
  }

  /** Gets the value of "letter-spacing" */
  String get letterSpacing => getPropertyValue('letter-spacing');

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    setProperty('letter-spacing', value, '');
  }

  /** Gets the value of "line-box-contain" */
  String get lineBoxContain => getPropertyValue('line-box-contain');

  /** Sets the value of "line-box-contain" */
  set lineBoxContain(String value) {
    setProperty('line-box-contain', value, '');
  }

  /** Gets the value of "line-break" */
  String get lineBreak => getPropertyValue('line-break');

  /** Sets the value of "line-break" */
  set lineBreak(String value) {
    setProperty('line-break', value, '');
  }

  /** Gets the value of "line-clamp" */
  String get lineClamp => getPropertyValue('line-clamp');

  /** Sets the value of "line-clamp" */
  set lineClamp(String value) {
    setProperty('line-clamp', value, '');
  }

  /** Gets the value of "line-height" */
  String get lineHeight => getPropertyValue('line-height');

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    setProperty('line-height', value, '');
  }

  /** Gets the value of "list-style" */
  String get listStyle => getPropertyValue('list-style');

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    setProperty('list-style', value, '');
  }

  /** Gets the value of "list-style-image" */
  String get listStyleImage => getPropertyValue('list-style-image');

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    setProperty('list-style-image', value, '');
  }

  /** Gets the value of "list-style-position" */
  String get listStylePosition => getPropertyValue('list-style-position');

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    setProperty('list-style-position', value, '');
  }

  /** Gets the value of "list-style-type" */
  String get listStyleType => getPropertyValue('list-style-type');

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    setProperty('list-style-type', value, '');
  }

  /** Gets the value of "locale" */
  String get locale => getPropertyValue('locale');

  /** Sets the value of "locale" */
  set locale(String value) {
    setProperty('locale', value, '');
  }

  /** Gets the value of "logical-height" */
  String get logicalHeight => getPropertyValue('logical-height');

  /** Sets the value of "logical-height" */
  set logicalHeight(String value) {
    setProperty('logical-height', value, '');
  }

  /** Gets the value of "logical-width" */
  String get logicalWidth => getPropertyValue('logical-width');

  /** Sets the value of "logical-width" */
  set logicalWidth(String value) {
    setProperty('logical-width', value, '');
  }

  /** Gets the value of "margin" */
  String get margin => getPropertyValue('margin');

  /** Sets the value of "margin" */
  set margin(String value) {
    setProperty('margin', value, '');
  }

  /** Gets the value of "margin-after" */
  String get marginAfter => getPropertyValue('margin-after');

  /** Sets the value of "margin-after" */
  set marginAfter(String value) {
    setProperty('margin-after', value, '');
  }

  /** Gets the value of "margin-after-collapse" */
  String get marginAfterCollapse => getPropertyValue('margin-after-collapse');

  /** Sets the value of "margin-after-collapse" */
  set marginAfterCollapse(String value) {
    setProperty('margin-after-collapse', value, '');
  }

  /** Gets the value of "margin-before" */
  String get marginBefore => getPropertyValue('margin-before');

  /** Sets the value of "margin-before" */
  set marginBefore(String value) {
    setProperty('margin-before', value, '');
  }

  /** Gets the value of "margin-before-collapse" */
  String get marginBeforeCollapse => getPropertyValue('margin-before-collapse');

  /** Sets the value of "margin-before-collapse" */
  set marginBeforeCollapse(String value) {
    setProperty('margin-before-collapse', value, '');
  }

  /** Gets the value of "margin-bottom" */
  String get marginBottom => getPropertyValue('margin-bottom');

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    setProperty('margin-bottom', value, '');
  }

  /** Gets the value of "margin-bottom-collapse" */
  String get marginBottomCollapse => getPropertyValue('margin-bottom-collapse');

  /** Sets the value of "margin-bottom-collapse" */
  set marginBottomCollapse(String value) {
    setProperty('margin-bottom-collapse', value, '');
  }

  /** Gets the value of "margin-collapse" */
  String get marginCollapse => getPropertyValue('margin-collapse');

  /** Sets the value of "margin-collapse" */
  set marginCollapse(String value) {
    setProperty('margin-collapse', value, '');
  }

  /** Gets the value of "margin-end" */
  String get marginEnd => getPropertyValue('margin-end');

  /** Sets the value of "margin-end" */
  set marginEnd(String value) {
    setProperty('margin-end', value, '');
  }

  /** Gets the value of "margin-left" */
  String get marginLeft => getPropertyValue('margin-left');

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    setProperty('margin-left', value, '');
  }

  /** Gets the value of "margin-right" */
  String get marginRight => getPropertyValue('margin-right');

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    setProperty('margin-right', value, '');
  }

  /** Gets the value of "margin-start" */
  String get marginStart => getPropertyValue('margin-start');

  /** Sets the value of "margin-start" */
  set marginStart(String value) {
    setProperty('margin-start', value, '');
  }

  /** Gets the value of "margin-top" */
  String get marginTop => getPropertyValue('margin-top');

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    setProperty('margin-top', value, '');
  }

  /** Gets the value of "margin-top-collapse" */
  String get marginTopCollapse => getPropertyValue('margin-top-collapse');

  /** Sets the value of "margin-top-collapse" */
  set marginTopCollapse(String value) {
    setProperty('margin-top-collapse', value, '');
  }

  /** Gets the value of "mask" */
  String get mask => getPropertyValue('mask');

  /** Sets the value of "mask" */
  set mask(String value) {
    setProperty('mask', value, '');
  }

  /** Gets the value of "mask-box-image" */
  String get maskBoxImage => getPropertyValue('mask-box-image');

  /** Sets the value of "mask-box-image" */
  set maskBoxImage(String value) {
    setProperty('mask-box-image', value, '');
  }

  /** Gets the value of "mask-box-image-outset" */
  String get maskBoxImageOutset => getPropertyValue('mask-box-image-outset');

  /** Sets the value of "mask-box-image-outset" */
  set maskBoxImageOutset(String value) {
    setProperty('mask-box-image-outset', value, '');
  }

  /** Gets the value of "mask-box-image-repeat" */
  String get maskBoxImageRepeat => getPropertyValue('mask-box-image-repeat');

  /** Sets the value of "mask-box-image-repeat" */
  set maskBoxImageRepeat(String value) {
    setProperty('mask-box-image-repeat', value, '');
  }

  /** Gets the value of "mask-box-image-slice" */
  String get maskBoxImageSlice => getPropertyValue('mask-box-image-slice');

  /** Sets the value of "mask-box-image-slice" */
  set maskBoxImageSlice(String value) {
    setProperty('mask-box-image-slice', value, '');
  }

  /** Gets the value of "mask-box-image-source" */
  String get maskBoxImageSource => getPropertyValue('mask-box-image-source');

  /** Sets the value of "mask-box-image-source" */
  set maskBoxImageSource(String value) {
    setProperty('mask-box-image-source', value, '');
  }

  /** Gets the value of "mask-box-image-width" */
  String get maskBoxImageWidth => getPropertyValue('mask-box-image-width');

  /** Sets the value of "mask-box-image-width" */
  set maskBoxImageWidth(String value) {
    setProperty('mask-box-image-width', value, '');
  }

  /** Gets the value of "mask-clip" */
  String get maskClip => getPropertyValue('mask-clip');

  /** Sets the value of "mask-clip" */
  set maskClip(String value) {
    setProperty('mask-clip', value, '');
  }

  /** Gets the value of "mask-composite" */
  String get maskComposite => getPropertyValue('mask-composite');

  /** Sets the value of "mask-composite" */
  set maskComposite(String value) {
    setProperty('mask-composite', value, '');
  }

  /** Gets the value of "mask-image" */
  String get maskImage => getPropertyValue('mask-image');

  /** Sets the value of "mask-image" */
  set maskImage(String value) {
    setProperty('mask-image', value, '');
  }

  /** Gets the value of "mask-origin" */
  String get maskOrigin => getPropertyValue('mask-origin');

  /** Sets the value of "mask-origin" */
  set maskOrigin(String value) {
    setProperty('mask-origin', value, '');
  }

  /** Gets the value of "mask-position" */
  String get maskPosition => getPropertyValue('mask-position');

  /** Sets the value of "mask-position" */
  set maskPosition(String value) {
    setProperty('mask-position', value, '');
  }

  /** Gets the value of "mask-position-x" */
  String get maskPositionX => getPropertyValue('mask-position-x');

  /** Sets the value of "mask-position-x" */
  set maskPositionX(String value) {
    setProperty('mask-position-x', value, '');
  }

  /** Gets the value of "mask-position-y" */
  String get maskPositionY => getPropertyValue('mask-position-y');

  /** Sets the value of "mask-position-y" */
  set maskPositionY(String value) {
    setProperty('mask-position-y', value, '');
  }

  /** Gets the value of "mask-repeat" */
  String get maskRepeat => getPropertyValue('mask-repeat');

  /** Sets the value of "mask-repeat" */
  set maskRepeat(String value) {
    setProperty('mask-repeat', value, '');
  }

  /** Gets the value of "mask-repeat-x" */
  String get maskRepeatX => getPropertyValue('mask-repeat-x');

  /** Sets the value of "mask-repeat-x" */
  set maskRepeatX(String value) {
    setProperty('mask-repeat-x', value, '');
  }

  /** Gets the value of "mask-repeat-y" */
  String get maskRepeatY => getPropertyValue('mask-repeat-y');

  /** Sets the value of "mask-repeat-y" */
  set maskRepeatY(String value) {
    setProperty('mask-repeat-y', value, '');
  }

  /** Gets the value of "mask-size" */
  String get maskSize => getPropertyValue('mask-size');

  /** Sets the value of "mask-size" */
  set maskSize(String value) {
    setProperty('mask-size', value, '');
  }

  /** Gets the value of "mask-source-type" */
  String get maskSourceType => getPropertyValue('mask-source-type');

  /** Sets the value of "mask-source-type" */
  set maskSourceType(String value) {
    setProperty('mask-source-type', value, '');
  }

  /** Gets the value of "max-height" */
  String get maxHeight => getPropertyValue('max-height');

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    setProperty('max-height', value, '');
  }

  /** Gets the value of "max-logical-height" */
  String get maxLogicalHeight => getPropertyValue('max-logical-height');

  /** Sets the value of "max-logical-height" */
  set maxLogicalHeight(String value) {
    setProperty('max-logical-height', value, '');
  }

  /** Gets the value of "max-logical-width" */
  String get maxLogicalWidth => getPropertyValue('max-logical-width');

  /** Sets the value of "max-logical-width" */
  set maxLogicalWidth(String value) {
    setProperty('max-logical-width', value, '');
  }

  /** Gets the value of "max-width" */
  String get maxWidth => getPropertyValue('max-width');

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    setProperty('max-width', value, '');
  }

  /** Gets the value of "max-zoom" */
  String get maxZoom => getPropertyValue('max-zoom');

  /** Sets the value of "max-zoom" */
  set maxZoom(String value) {
    setProperty('max-zoom', value, '');
  }

  /** Gets the value of "min-height" */
  String get minHeight => getPropertyValue('min-height');

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    setProperty('min-height', value, '');
  }

  /** Gets the value of "min-logical-height" */
  String get minLogicalHeight => getPropertyValue('min-logical-height');

  /** Sets the value of "min-logical-height" */
  set minLogicalHeight(String value) {
    setProperty('min-logical-height', value, '');
  }

  /** Gets the value of "min-logical-width" */
  String get minLogicalWidth => getPropertyValue('min-logical-width');

  /** Sets the value of "min-logical-width" */
  set minLogicalWidth(String value) {
    setProperty('min-logical-width', value, '');
  }

  /** Gets the value of "min-width" */
  String get minWidth => getPropertyValue('min-width');

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    setProperty('min-width', value, '');
  }

  /** Gets the value of "min-zoom" */
  String get minZoom => getPropertyValue('min-zoom');

  /** Sets the value of "min-zoom" */
  set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

  /** Gets the value of "mix-blend-mode" */
  String get mixBlendMode => getPropertyValue('mix-blend-mode');

  /** Sets the value of "mix-blend-mode" */
  set mixBlendMode(String value) {
    setProperty('mix-blend-mode', value, '');
  }

  /** Gets the value of "object-fit" */
  String get objectFit => getPropertyValue('object-fit');

  /** Sets the value of "object-fit" */
  set objectFit(String value) {
    setProperty('object-fit', value, '');
  }

  /** Gets the value of "object-position" */
  String get objectPosition => getPropertyValue('object-position');

  /** Sets the value of "object-position" */
  set objectPosition(String value) {
    setProperty('object-position', value, '');
  }

  /** Gets the value of "opacity" */
  String get opacity => getPropertyValue('opacity');

  /** Sets the value of "opacity" */
  set opacity(String value) {
    setProperty('opacity', value, '');
  }

  /** Gets the value of "order" */
  String get order => getPropertyValue('order');

  /** Sets the value of "order" */
  set order(String value) {
    setProperty('order', value, '');
  }

  /** Gets the value of "orientation" */
  String get orientation => getPropertyValue('orientation');

  /** Sets the value of "orientation" */
  set orientation(String value) {
    setProperty('orientation', value, '');
  }

  /** Gets the value of "orphans" */
  String get orphans => getPropertyValue('orphans');

  /** Sets the value of "orphans" */
  set orphans(String value) {
    setProperty('orphans', value, '');
  }

  /** Gets the value of "outline" */
  String get outline => getPropertyValue('outline');

  /** Sets the value of "outline" */
  set outline(String value) {
    setProperty('outline', value, '');
  }

  /** Gets the value of "outline-color" */
  String get outlineColor => getPropertyValue('outline-color');

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    setProperty('outline-color', value, '');
  }

  /** Gets the value of "outline-offset" */
  String get outlineOffset => getPropertyValue('outline-offset');

  /** Sets the value of "outline-offset" */
  set outlineOffset(String value) {
    setProperty('outline-offset', value, '');
  }

  /** Gets the value of "outline-style" */
  String get outlineStyle => getPropertyValue('outline-style');

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    setProperty('outline-style', value, '');
  }

  /** Gets the value of "outline-width" */
  String get outlineWidth => getPropertyValue('outline-width');

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    setProperty('outline-width', value, '');
  }

  /** Gets the value of "overflow" */
  String get overflow => getPropertyValue('overflow');

  /** Sets the value of "overflow" */
  set overflow(String value) {
    setProperty('overflow', value, '');
  }

  /** Gets the value of "overflow-wrap" */
  String get overflowWrap => getPropertyValue('overflow-wrap');

  /** Sets the value of "overflow-wrap" */
  set overflowWrap(String value) {
    setProperty('overflow-wrap', value, '');
  }

  /** Gets the value of "overflow-x" */
  String get overflowX => getPropertyValue('overflow-x');

  /** Sets the value of "overflow-x" */
  set overflowX(String value) {
    setProperty('overflow-x', value, '');
  }

  /** Gets the value of "overflow-y" */
  String get overflowY => getPropertyValue('overflow-y');

  /** Sets the value of "overflow-y" */
  set overflowY(String value) {
    setProperty('overflow-y', value, '');
  }

  /** Gets the value of "padding" */
  String get padding => getPropertyValue('padding');

  /** Sets the value of "padding" */
  set padding(String value) {
    setProperty('padding', value, '');
  }

  /** Gets the value of "padding-after" */
  String get paddingAfter => getPropertyValue('padding-after');

  /** Sets the value of "padding-after" */
  set paddingAfter(String value) {
    setProperty('padding-after', value, '');
  }

  /** Gets the value of "padding-before" */
  String get paddingBefore => getPropertyValue('padding-before');

  /** Sets the value of "padding-before" */
  set paddingBefore(String value) {
    setProperty('padding-before', value, '');
  }

  /** Gets the value of "padding-bottom" */
  String get paddingBottom => getPropertyValue('padding-bottom');

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    setProperty('padding-bottom', value, '');
  }

  /** Gets the value of "padding-end" */
  String get paddingEnd => getPropertyValue('padding-end');

  /** Sets the value of "padding-end" */
  set paddingEnd(String value) {
    setProperty('padding-end', value, '');
  }

  /** Gets the value of "padding-left" */
  String get paddingLeft => getPropertyValue('padding-left');

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    setProperty('padding-left', value, '');
  }

  /** Gets the value of "padding-right" */
  String get paddingRight => getPropertyValue('padding-right');

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    setProperty('padding-right', value, '');
  }

  /** Gets the value of "padding-start" */
  String get paddingStart => getPropertyValue('padding-start');

  /** Sets the value of "padding-start" */
  set paddingStart(String value) {
    setProperty('padding-start', value, '');
  }

  /** Gets the value of "padding-top" */
  String get paddingTop => getPropertyValue('padding-top');

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

  /** Gets the value of "page" */
  String get page => getPropertyValue('page');

  /** Sets the value of "page" */
  set page(String value) {
    setProperty('page', value, '');
  }

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => getPropertyValue('page-break-after');

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    setProperty('page-break-after', value, '');
  }

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => getPropertyValue('page-break-before');

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    setProperty('page-break-before', value, '');
  }

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => getPropertyValue('page-break-inside');

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    setProperty('page-break-inside', value, '');
  }

  /** Gets the value of "perspective" */
  String get perspective => getPropertyValue('perspective');

  /** Sets the value of "perspective" */
  set perspective(String value) {
    setProperty('perspective', value, '');
  }

  /** Gets the value of "perspective-origin" */
  String get perspectiveOrigin => getPropertyValue('perspective-origin');

  /** Sets the value of "perspective-origin" */
  set perspectiveOrigin(String value) {
    setProperty('perspective-origin', value, '');
  }

  /** Gets the value of "perspective-origin-x" */
  String get perspectiveOriginX => getPropertyValue('perspective-origin-x');

  /** Sets the value of "perspective-origin-x" */
  set perspectiveOriginX(String value) {
    setProperty('perspective-origin-x', value, '');
  }

  /** Gets the value of "perspective-origin-y" */
  String get perspectiveOriginY => getPropertyValue('perspective-origin-y');

  /** Sets the value of "perspective-origin-y" */
  set perspectiveOriginY(String value) {
    setProperty('perspective-origin-y', value, '');
  }

  /** Gets the value of "pointer-events" */
  String get pointerEvents => getPropertyValue('pointer-events');

  /** Sets the value of "pointer-events" */
  set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

  /** Gets the value of "position" */
  String get position => getPropertyValue('position');

  /** Sets the value of "position" */
  set position(String value) {
    setProperty('position', value, '');
  }

  /** Gets the value of "print-color-adjust" */
  String get printColorAdjust => getPropertyValue('print-color-adjust');

  /** Sets the value of "print-color-adjust" */
  set printColorAdjust(String value) {
    setProperty('print-color-adjust', value, '');
  }

  /** Gets the value of "quotes" */
  String get quotes => getPropertyValue('quotes');

  /** Sets the value of "quotes" */
  set quotes(String value) {
    setProperty('quotes', value, '');
  }

  /** Gets the value of "resize" */
  String get resize => getPropertyValue('resize');

  /** Sets the value of "resize" */
  set resize(String value) {
    setProperty('resize', value, '');
  }

  /** Gets the value of "right" */
  String get right => getPropertyValue('right');

  /** Sets the value of "right" */
  set right(String value) {
    setProperty('right', value, '');
  }

  /** Gets the value of "rtl-ordering" */
  String get rtlOrdering => getPropertyValue('rtl-ordering');

  /** Sets the value of "rtl-ordering" */
  set rtlOrdering(String value) {
    setProperty('rtl-ordering', value, '');
  }

  /** Gets the value of "ruby-position" */
  String get rubyPosition => getPropertyValue('ruby-position');

  /** Sets the value of "ruby-position" */
  set rubyPosition(String value) {
    setProperty('ruby-position', value, '');
  }

  /** Gets the value of "scroll-behavior" */
  String get scrollBehavior => getPropertyValue('scroll-behavior');

  /** Sets the value of "scroll-behavior" */
  set scrollBehavior(String value) {
    setProperty('scroll-behavior', value, '');
  }

  /** Gets the value of "shape-image-threshold" */
  String get shapeImageThreshold => getPropertyValue('shape-image-threshold');

  /** Sets the value of "shape-image-threshold" */
  set shapeImageThreshold(String value) {
    setProperty('shape-image-threshold', value, '');
  }

  /** Gets the value of "shape-margin" */
  String get shapeMargin => getPropertyValue('shape-margin');

  /** Sets the value of "shape-margin" */
  set shapeMargin(String value) {
    setProperty('shape-margin', value, '');
  }

  /** Gets the value of "shape-outside" */
  String get shapeOutside => getPropertyValue('shape-outside');

  /** Sets the value of "shape-outside" */
  set shapeOutside(String value) {
    setProperty('shape-outside', value, '');
  }

  /** Gets the value of "size" */
  String get size => getPropertyValue('size');

  /** Sets the value of "size" */
  set size(String value) {
    setProperty('size', value, '');
  }

  /** Gets the value of "speak" */
  String get speak => getPropertyValue('speak');

  /** Sets the value of "speak" */
  set speak(String value) {
    setProperty('speak', value, '');
  }

  /** Gets the value of "src" */
  String get src => getPropertyValue('src');

  /** Sets the value of "src" */
  set src(String value) {
    setProperty('src', value, '');
  }

  /** Gets the value of "tab-size" */
  String get tabSize => getPropertyValue('tab-size');

  /** Sets the value of "tab-size" */
  set tabSize(String value) {
    setProperty('tab-size', value, '');
  }

  /** Gets the value of "table-layout" */
  String get tableLayout => getPropertyValue('table-layout');

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

  /** Gets the value of "tap-highlight-color" */
  String get tapHighlightColor => getPropertyValue('tap-highlight-color');

  /** Sets the value of "tap-highlight-color" */
  set tapHighlightColor(String value) {
    setProperty('tap-highlight-color', value, '');
  }

  /** Gets the value of "text-align" */
  String get textAlign => getPropertyValue('text-align');

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    setProperty('text-align', value, '');
  }

  /** Gets the value of "text-align-last" */
  String get textAlignLast => getPropertyValue('text-align-last');

  /** Sets the value of "text-align-last" */
  set textAlignLast(String value) {
    setProperty('text-align-last', value, '');
  }

  /** Gets the value of "text-combine" */
  String get textCombine => getPropertyValue('text-combine');

  /** Sets the value of "text-combine" */
  set textCombine(String value) {
    setProperty('text-combine', value, '');
  }

  /** Gets the value of "text-decoration" */
  String get textDecoration => getPropertyValue('text-decoration');

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    setProperty('text-decoration', value, '');
  }

  /** Gets the value of "text-decoration-color" */
  String get textDecorationColor => getPropertyValue('text-decoration-color');

  /** Sets the value of "text-decoration-color" */
  set textDecorationColor(String value) {
    setProperty('text-decoration-color', value, '');
  }

  /** Gets the value of "text-decoration-line" */
  String get textDecorationLine => getPropertyValue('text-decoration-line');

  /** Sets the value of "text-decoration-line" */
  set textDecorationLine(String value) {
    setProperty('text-decoration-line', value, '');
  }

  /** Gets the value of "text-decoration-style" */
  String get textDecorationStyle => getPropertyValue('text-decoration-style');

  /** Sets the value of "text-decoration-style" */
  set textDecorationStyle(String value) {
    setProperty('text-decoration-style', value, '');
  }

  /** Gets the value of "text-decorations-in-effect" */
  String get textDecorationsInEffect =>
      getPropertyValue('text-decorations-in-effect');

  /** Sets the value of "text-decorations-in-effect" */
  set textDecorationsInEffect(String value) {
    setProperty('text-decorations-in-effect', value, '');
  }

  /** Gets the value of "text-emphasis" */
  String get textEmphasis => getPropertyValue('text-emphasis');

  /** Sets the value of "text-emphasis" */
  set textEmphasis(String value) {
    setProperty('text-emphasis', value, '');
  }

  /** Gets the value of "text-emphasis-color" */
  String get textEmphasisColor => getPropertyValue('text-emphasis-color');

  /** Sets the value of "text-emphasis-color" */
  set textEmphasisColor(String value) {
    setProperty('text-emphasis-color', value, '');
  }

  /** Gets the value of "text-emphasis-position" */
  String get textEmphasisPosition => getPropertyValue('text-emphasis-position');

  /** Sets the value of "text-emphasis-position" */
  set textEmphasisPosition(String value) {
    setProperty('text-emphasis-position', value, '');
  }

  /** Gets the value of "text-emphasis-style" */
  String get textEmphasisStyle => getPropertyValue('text-emphasis-style');

  /** Sets the value of "text-emphasis-style" */
  set textEmphasisStyle(String value) {
    setProperty('text-emphasis-style', value, '');
  }

  /** Gets the value of "text-fill-color" */
  String get textFillColor => getPropertyValue('text-fill-color');

  /** Sets the value of "text-fill-color" */
  set textFillColor(String value) {
    setProperty('text-fill-color', value, '');
  }

  /** Gets the value of "text-indent" */
  String get textIndent => getPropertyValue('text-indent');

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    setProperty('text-indent', value, '');
  }

  /** Gets the value of "text-justify" */
  String get textJustify => getPropertyValue('text-justify');

  /** Sets the value of "text-justify" */
  set textJustify(String value) {
    setProperty('text-justify', value, '');
  }

  /** Gets the value of "text-line-through-color" */
  String get textLineThroughColor =>
      getPropertyValue('text-line-through-color');

  /** Sets the value of "text-line-through-color" */
  set textLineThroughColor(String value) {
    setProperty('text-line-through-color', value, '');
  }

  /** Gets the value of "text-line-through-mode" */
  String get textLineThroughMode => getPropertyValue('text-line-through-mode');

  /** Sets the value of "text-line-through-mode" */
  set textLineThroughMode(String value) {
    setProperty('text-line-through-mode', value, '');
  }

  /** Gets the value of "text-line-through-style" */
  String get textLineThroughStyle =>
      getPropertyValue('text-line-through-style');

  /** Sets the value of "text-line-through-style" */
  set textLineThroughStyle(String value) {
    setProperty('text-line-through-style', value, '');
  }

  /** Gets the value of "text-line-through-width" */
  String get textLineThroughWidth =>
      getPropertyValue('text-line-through-width');

  /** Sets the value of "text-line-through-width" */
  set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

  /** Gets the value of "text-orientation" */
  String get textOrientation => getPropertyValue('text-orientation');

  /** Sets the value of "text-orientation" */
  set textOrientation(String value) {
    setProperty('text-orientation', value, '');
  }

  /** Gets the value of "text-overflow" */
  String get textOverflow => getPropertyValue('text-overflow');

  /** Sets the value of "text-overflow" */
  set textOverflow(String value) {
    setProperty('text-overflow', value, '');
  }

  /** Gets the value of "text-overline-color" */
  String get textOverlineColor => getPropertyValue('text-overline-color');

  /** Sets the value of "text-overline-color" */
  set textOverlineColor(String value) {
    setProperty('text-overline-color', value, '');
  }

  /** Gets the value of "text-overline-mode" */
  String get textOverlineMode => getPropertyValue('text-overline-mode');

  /** Sets the value of "text-overline-mode" */
  set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

  /** Gets the value of "text-overline-style" */
  String get textOverlineStyle => getPropertyValue('text-overline-style');

  /** Sets the value of "text-overline-style" */
  set textOverlineStyle(String value) {
    setProperty('text-overline-style', value, '');
  }

  /** Gets the value of "text-overline-width" */
  String get textOverlineWidth => getPropertyValue('text-overline-width');

  /** Sets the value of "text-overline-width" */
  set textOverlineWidth(String value) {
    setProperty('text-overline-width', value, '');
  }

  /** Gets the value of "text-rendering" */
  String get textRendering => getPropertyValue('text-rendering');

  /** Sets the value of "text-rendering" */
  set textRendering(String value) {
    setProperty('text-rendering', value, '');
  }

  /** Gets the value of "text-security" */
  String get textSecurity => getPropertyValue('text-security');

  /** Sets the value of "text-security" */
  set textSecurity(String value) {
    setProperty('text-security', value, '');
  }

  /** Gets the value of "text-shadow" */
  String get textShadow => getPropertyValue('text-shadow');

  /** Sets the value of "text-shadow" */
  set textShadow(String value) {
    setProperty('text-shadow', value, '');
  }

  /** Gets the value of "text-stroke" */
  String get textStroke => getPropertyValue('text-stroke');

  /** Sets the value of "text-stroke" */
  set textStroke(String value) {
    setProperty('text-stroke', value, '');
  }

  /** Gets the value of "text-stroke-color" */
  String get textStrokeColor => getPropertyValue('text-stroke-color');

  /** Sets the value of "text-stroke-color" */
  set textStrokeColor(String value) {
    setProperty('text-stroke-color', value, '');
  }

  /** Gets the value of "text-stroke-width" */
  String get textStrokeWidth => getPropertyValue('text-stroke-width');

  /** Sets the value of "text-stroke-width" */
  set textStrokeWidth(String value) {
    setProperty('text-stroke-width', value, '');
  }

  /** Gets the value of "text-transform" */
  String get textTransform => getPropertyValue('text-transform');

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    setProperty('text-transform', value, '');
  }

  /** Gets the value of "text-underline-color" */
  String get textUnderlineColor => getPropertyValue('text-underline-color');

  /** Sets the value of "text-underline-color" */
  set textUnderlineColor(String value) {
    setProperty('text-underline-color', value, '');
  }

  /** Gets the value of "text-underline-mode" */
  String get textUnderlineMode => getPropertyValue('text-underline-mode');

  /** Sets the value of "text-underline-mode" */
  set textUnderlineMode(String value) {
    setProperty('text-underline-mode', value, '');
  }

  /** Gets the value of "text-underline-position" */
  String get textUnderlinePosition =>
      getPropertyValue('text-underline-position');

  /** Sets the value of "text-underline-position" */
  set textUnderlinePosition(String value) {
    setProperty('text-underline-position', value, '');
  }

  /** Gets the value of "text-underline-style" */
  String get textUnderlineStyle => getPropertyValue('text-underline-style');

  /** Sets the value of "text-underline-style" */
  set textUnderlineStyle(String value) {
    setProperty('text-underline-style', value, '');
  }

  /** Gets the value of "text-underline-width" */
  String get textUnderlineWidth => getPropertyValue('text-underline-width');

  /** Sets the value of "text-underline-width" */
  set textUnderlineWidth(String value) {
    setProperty('text-underline-width', value, '');
  }

  /** Gets the value of "top" */
  String get top => getPropertyValue('top');

  /** Sets the value of "top" */
  set top(String value) {
    setProperty('top', value, '');
  }

  /** Gets the value of "touch-action" */
  String get touchAction => getPropertyValue('touch-action');

  /** Sets the value of "touch-action" */
  set touchAction(String value) {
    setProperty('touch-action', value, '');
  }

  /** Gets the value of "touch-action-delay" */
  String get touchActionDelay => getPropertyValue('touch-action-delay');

  /** Sets the value of "touch-action-delay" */
  set touchActionDelay(String value) {
    setProperty('touch-action-delay', value, '');
  }

  /** Gets the value of "transform" */
  String get transform => getPropertyValue('transform');

  /** Sets the value of "transform" */
  set transform(String value) {
    setProperty('transform', value, '');
  }

  /** Gets the value of "transform-origin" */
  String get transformOrigin => getPropertyValue('transform-origin');

  /** Sets the value of "transform-origin" */
  set transformOrigin(String value) {
    setProperty('transform-origin', value, '');
  }

  /** Gets the value of "transform-origin-x" */
  String get transformOriginX => getPropertyValue('transform-origin-x');

  /** Sets the value of "transform-origin-x" */
  set transformOriginX(String value) {
    setProperty('transform-origin-x', value, '');
  }

  /** Gets the value of "transform-origin-y" */
  String get transformOriginY => getPropertyValue('transform-origin-y');

  /** Sets the value of "transform-origin-y" */
  set transformOriginY(String value) {
    setProperty('transform-origin-y', value, '');
  }

  /** Gets the value of "transform-origin-z" */
  String get transformOriginZ => getPropertyValue('transform-origin-z');

  /** Sets the value of "transform-origin-z" */
  set transformOriginZ(String value) {
    setProperty('transform-origin-z', value, '');
  }

  /** Gets the value of "transform-style" */
  String get transformStyle => getPropertyValue('transform-style');

  /** Sets the value of "transform-style" */
  set transformStyle(String value) {
    setProperty('transform-style', value, '');
  }

  /** Gets the value of "transition" */ @SupportedBrowser(
      SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String get transition => getPropertyValue('transition');

  /** Sets the value of "transition" */ @SupportedBrowser(
      SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  set transition(String value) {
    setProperty('transition', value, '');
  }

  /** Gets the value of "transition-delay" */
  String get transitionDelay => getPropertyValue('transition-delay');

  /** Sets the value of "transition-delay" */
  set transitionDelay(String value) {
    setProperty('transition-delay', value, '');
  }

  /** Gets the value of "transition-duration" */
  String get transitionDuration => getPropertyValue('transition-duration');

  /** Sets the value of "transition-duration" */
  set transitionDuration(String value) {
    setProperty('transition-duration', value, '');
  }

  /** Gets the value of "transition-property" */
  String get transitionProperty => getPropertyValue('transition-property');

  /** Sets the value of "transition-property" */
  set transitionProperty(String value) {
    setProperty('transition-property', value, '');
  }

  /** Gets the value of "transition-timing-function" */
  String get transitionTimingFunction =>
      getPropertyValue('transition-timing-function');

  /** Sets the value of "transition-timing-function" */
  set transitionTimingFunction(String value) {
    setProperty('transition-timing-function', value, '');
  }

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => getPropertyValue('unicode-bidi');

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    setProperty('unicode-bidi', value, '');
  }

  /** Gets the value of "unicode-range" */
  String get unicodeRange => getPropertyValue('unicode-range');

  /** Sets the value of "unicode-range" */
  set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

  /** Gets the value of "user-drag" */
  String get userDrag => getPropertyValue('user-drag');

  /** Sets the value of "user-drag" */
  set userDrag(String value) {
    setProperty('user-drag', value, '');
  }

  /** Gets the value of "user-modify" */
  String get userModify => getPropertyValue('user-modify');

  /** Sets the value of "user-modify" */
  set userModify(String value) {
    setProperty('user-modify', value, '');
  }

  /** Gets the value of "user-select" */
  String get userSelect => getPropertyValue('user-select');

  /** Sets the value of "user-select" */
  set userSelect(String value) {
    setProperty('user-select', value, '');
  }

  /** Gets the value of "user-zoom" */
  String get userZoom => getPropertyValue('user-zoom');

  /** Sets the value of "user-zoom" */
  set userZoom(String value) {
    setProperty('user-zoom', value, '');
  }

  /** Gets the value of "vertical-align" */
  String get verticalAlign => getPropertyValue('vertical-align');

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

  /** Gets the value of "visibility" */
  String get visibility => getPropertyValue('visibility');

  /** Sets the value of "visibility" */
  set visibility(String value) {
    setProperty('visibility', value, '');
  }

  /** Gets the value of "white-space" */
  String get whiteSpace => getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

  /** Gets the value of "widows" */
  String get widows => getPropertyValue('widows');

  /** Sets the value of "widows" */
  set widows(String value) {
    setProperty('widows', value, '');
  }

  /** Gets the value of "width" */
  String get width => getPropertyValue('width');

  /** Sets the value of "width" */
  set width(String value) {
    setProperty('width', value, '');
  }

  /** Gets the value of "will-change" */
  String get willChange => getPropertyValue('will-change');

  /** Sets the value of "will-change" */
  set willChange(String value) {
    setProperty('will-change', value, '');
  }

  /** Gets the value of "word-break" */
  String get wordBreak => getPropertyValue('word-break');

  /** Sets the value of "word-break" */
  set wordBreak(String value) {
    setProperty('word-break', value, '');
  }

  /** Gets the value of "word-spacing" */
  String get wordSpacing => getPropertyValue('word-spacing');

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    setProperty('word-spacing', value, '');
  }

  /** Gets the value of "word-wrap" */
  String get wordWrap => getPropertyValue('word-wrap');

  /** Sets the value of "word-wrap" */
  set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

  /** Gets the value of "wrap-flow" */
  String get wrapFlow => getPropertyValue('wrap-flow');

  /** Sets the value of "wrap-flow" */
  set wrapFlow(String value) {
    setProperty('wrap-flow', value, '');
  }

  /** Gets the value of "wrap-through" */
  String get wrapThrough => getPropertyValue('wrap-through');

  /** Sets the value of "wrap-through" */
  set wrapThrough(String value) {
    setProperty('wrap-through', value, '');
  }

  /** Gets the value of "writing-mode" */
  String get writingMode => getPropertyValue('writing-mode');

  /** Sets the value of "writing-mode" */
  set writingMode(String value) {
    setProperty('writing-mode', value, '');
  }

  /** Gets the value of "z-index" */
  String get zIndex => getPropertyValue('z-index');

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    setProperty('z-index', value, '');
  }

  /** Gets the value of "zoom" */
  String get zoom => getPropertyValue('zoom');

  /** Sets the value of "zoom" */
  set zoom(String value) {
    setProperty('zoom', value, '');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSStyleRule")
class CssStyleRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssStyleRule._() {
    throw new UnsupportedError("Not supported");
  }

  String selectorText;

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSStyleSheet")
class CssStyleSheet extends StyleSheet {
  // To suppress missing implicit constructor warnings.
  factory CssStyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  final CssRule ownerRule;

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> rules;

  int addRule(String selector, String style, [int index]) native;

  void deleteRule(int index) native;

  int insertRule(String rule, [int index]) native;

  void removeRule(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSStyleValue")
class CssStyleValue extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssStyleValue._() {
    throw new UnsupportedError("Not supported");
  }

  static Object parse(String property, String cssText) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSSupportsRule")
class CssSupportsRule extends CssConditionRule {
  // To suppress missing implicit constructor warnings.
  factory CssSupportsRule._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSTransformComponent")
class CssTransformComponent extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssTransformComponent._() {
    throw new UnsupportedError("Not supported");
  }

  bool is2D;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSTransformValue")
class CssTransformValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssTransformValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssTransformValue([List<CssTransformComponent> transformComponents]) {
    if (transformComponents == null) {
      return CssTransformValue._create_1();
    }
    if ((transformComponents is List<CssTransformComponent>)) {
      return CssTransformValue._create_2(transformComponents);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssTransformValue _create_1() =>
      JS('CssTransformValue', 'new CSSTransformValue()');
  static CssTransformValue _create_2(transformComponents) =>
      JS('CssTransformValue', 'new CSSTransformValue(#)', transformComponents);

  final bool is2D;

  final int length;

  CssTransformComponent componentAtIndex(int index) native;

  DomMatrix toMatrix() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSTranslation")
class CssTranslation extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssTranslation._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssTranslation(CssNumericValue x, CssNumericValue y,
      [CssNumericValue z]) {
    if ((y is CssNumericValue) && (x is CssNumericValue) && z == null) {
      return CssTranslation._create_1(x, y);
    }
    if ((z is CssNumericValue) &&
        (y is CssNumericValue) &&
        (x is CssNumericValue)) {
      return CssTranslation._create_2(x, y, z);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssTranslation _create_1(x, y) =>
      JS('CssTranslation', 'new CSSTranslation(#,#)', x, y);
  static CssTranslation _create_2(x, y, z) =>
      JS('CssTranslation', 'new CSSTranslation(#,#,#)', x, y, z);

  CssNumericValue x;

  CssNumericValue y;

  CssNumericValue z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSUnitValue")
class CssUnitValue extends CssNumericValue {
  // To suppress missing implicit constructor warnings.
  factory CssUnitValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssUnitValue(num value, String unit) {
    return CssUnitValue._create_1(value, unit);
  }
  static CssUnitValue _create_1(value, unit) =>
      JS('CssUnitValue', 'new CSSUnitValue(#,#)', value, unit);

  final String type;

  String unit;

  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSUnparsedValue")
class CssUnparsedValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssUnparsedValue._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  Object fragmentAtIndex(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSVariableReferenceValue")
class CssVariableReferenceValue extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssVariableReferenceValue._() {
    throw new UnsupportedError("Not supported");
  }

  final CssUnparsedValue fallback;

  final String variable;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSViewportRule")
class CssViewportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssViewportRule._() {
    throw new UnsupportedError("Not supported");
  }

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSURLImageValue")
class CssurlImageValue extends CssImageValue {
  // To suppress missing implicit constructor warnings.
  factory CssurlImageValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssurlImageValue(String url) {
    return CssurlImageValue._create_1(url);
  }
  static CssurlImageValue _create_1(url) =>
      JS('CssurlImageValue', 'new CSSURLImageValue(#)', url);

  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-constructor-generation
@deprecated // experimental
typedef void CustomElementConstructor();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CustomElementRegistry")
class CustomElementRegistry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CustomElementRegistry._() {
    throw new UnsupportedError("Not supported");
  }

  void define(String name, Object constructor, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _define_1(name, constructor, options_1);
      return;
    }
    _define_2(name, constructor);
    return;
  }

  @JSName('define')
  void _define_1(name, constructor, options) native;
  @JSName('define')
  void _define_2(name, constructor) native;

  Object get(String name) native;

  Future whenDefined(String name) =>
      promiseToFuture(JS("", "#.whenDefined(#)", this, name));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("CustomEvent")
class CustomEvent extends Event {
  @Creates('Null') // Set from Dart code; does not instantiate a native type.
  var _dartDetail;

  factory CustomEvent(String type,
      {bool canBubble: true, bool cancelable: true, Object detail}) {
    final CustomEvent e = document._createEvent('CustomEvent');

    e._dartDetail = detail;

    // Only try setting the detail if it's one of these types to avoid
    // first-chance exceptions. Can expand this list in the future as needed.
    if (detail is List || detail is Map || detail is String || detail is num) {
      try {
        detail = convertDartToNative_SerializedScriptValue(detail);
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch (_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }

  factory CustomEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CustomEvent._create_1(type, eventInitDict_1);
    }
    return CustomEvent._create_2(type);
  }
  static CustomEvent _create_1(type, eventInitDict) =>
      JS('CustomEvent', 'new CustomEvent(#,#)', type, eventInitDict);
  static CustomEvent _create_2(type) =>
      JS('CustomEvent', 'new CustomEvent(#)', type);

  dynamic get _detail =>
      convertNativeToDart_SerializedScriptValue(this._get__detail);
  @JSName('detail')
  @Creates('Null')
  final dynamic _get__detail;

  @JSName('initCustomEvent')
  void _initCustomEvent(String type,
      [bool bubbles, bool cancelable, Object detail]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLDListElement")
class DListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DListElement() => JS(
      'returns:DListElement;creates:DListElement;new:true',
      '#.createElement(#)',
      document,
      "dl");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLDataElement")
class DataElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DataElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataElement.created() : super.created();

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLDataListElement")
class DataListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DataListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DataListElement() => document.createElement("datalist");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataListElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('datalist');

  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> options;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DataTransfer")
class DataTransfer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() {
    throw new UnsupportedError("Not supported");
  }

  factory DataTransfer() {
    return DataTransfer._create_1();
  }
  static DataTransfer _create_1() => JS('DataTransfer', 'new DataTransfer()');

  String dropEffect;

  String effectAllowed;

  @Returns('FileList|Null')
  @Creates('FileList')
  final List<File> files;

  final DataTransferItemList items;

  final List<String> types;

  void clearData([String format]) native;

  String getData(String format) native;

  void setData(String format, String data) native;

  void setDragImage(Element image, int x, int y) native;
}
// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DataTransferItem")
class DataTransferItem extends Interceptor {
  Entry getAsEntry() {
    Entry entry = _webkitGetAsEntry();

    if (entry.isFile)
      applyExtension('FileEntry', entry);
    else if (entry.isDirectory)
      applyExtension('DirectoryEntry', entry);
    else
      applyExtension('Entry', entry);

    return entry;
  }

  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() {
    throw new UnsupportedError("Not supported");
  }

  final String kind;

  final String type;

  File getAsFile() native;

  @JSName('webkitGetAsEntry')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Entry _webkitGetAsEntry() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DataTransferItemList")
class DataTransferItemList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  DataTransferItem add(data_OR_file, [String type]) native;

  @JSName('add')
  DataTransferItem addData(String data, String type) native;

  @JSName('add')
  DataTransferItem addFile(File file) native;

  void clear() native;

  DataTransferItem item(int index) native;

  void remove(int index) native;

  DataTransferItem operator [](int index) {
    return JS('DataTransferItem', '#[#]', this, index);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void DatabaseCallback(SqlDatabase database);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void DecodeErrorCallback(DomException error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void DecodeSuccessCallback(AudioBuffer decodedData);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DedicatedWorkerGlobalScope")
class DedicatedWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory DedicatedWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [DedicatedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  static const int PERSISTENT = 1;

  static const int TEMPORARY = 0;

  void close() native;

  void postMessage(/*any*/ message, [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message) native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitRequestFileSystem(int type, int size,
      [_FileSystemCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystemSync')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitResolveLocalFileSystemUrl(
      String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  static DedicatedWorkerGlobalScope get instance {
    return _workerSelf as DedicatedWorkerGlobalScope;
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeprecatedStorageInfo")
class DeprecatedStorageInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageInfo._() {
    throw new UnsupportedError("Not supported");
  }

  static const int PERSISTENT = 1;

  static const int TEMPORARY = 0;

  void queryUsageAndQuota(int storageType,
      [StorageUsageCallback usageCallback,
      StorageErrorCallback errorCallback]) native;

  void requestQuota(int storageType, int newQuotaInBytes,
      [StorageQuotaCallback quotaCallback,
      StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeprecatedStorageQuota")
class DeprecatedStorageQuota extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageQuota._() {
    throw new UnsupportedError("Not supported");
  }

  void queryUsageAndQuota(StorageUsageCallback usageCallback,
      [StorageErrorCallback errorCallback]) native;

  void requestQuota(int newQuotaInBytes,
      [StorageQuotaCallback quotaCallback,
      StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeprecationReport")
class DeprecationReport extends ReportBody {
  // To suppress missing implicit constructor warnings.
  factory DeprecationReport._() {
    throw new UnsupportedError("Not supported");
  }

  final int lineNumber;

  final String message;

  final String sourceFile;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLDetailsElement")
class DetailsElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DetailsElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetailsElement() => document.createElement("details");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DetailsElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('details');

  bool open;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DetectedBarcode")
class DetectedBarcode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DetectedBarcode._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetectedBarcode() {
    return DetectedBarcode._create_1();
  }
  static DetectedBarcode _create_1() =>
      JS('DetectedBarcode', 'new DetectedBarcode()');

  final Rectangle boundingBox;

  final List cornerPoints;

  final String rawValue;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DetectedFace")
class DetectedFace extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DetectedFace._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetectedFace() {
    return DetectedFace._create_1();
  }
  static DetectedFace _create_1() => JS('DetectedFace', 'new DetectedFace()');

  final Rectangle boundingBox;

  final List landmarks;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DetectedText")
class DetectedText extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DetectedText._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetectedText() {
    return DetectedText._create_1();
  }
  static DetectedText _create_1() => JS('DetectedText', 'new DetectedText()');

  final Rectangle boundingBox;

  final List cornerPoints;

  final String rawValue;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceAcceleration")
class DeviceAcceleration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() {
    throw new UnsupportedError("Not supported");
  }

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceMotionEvent")
class DeviceMotionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceMotionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory DeviceMotionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return DeviceMotionEvent._create_1(type, eventInitDict_1);
    }
    return DeviceMotionEvent._create_2(type);
  }
  static DeviceMotionEvent _create_1(type, eventInitDict) => JS(
      'DeviceMotionEvent', 'new DeviceMotionEvent(#,#)', type, eventInitDict);
  static DeviceMotionEvent _create_2(type) =>
      JS('DeviceMotionEvent', 'new DeviceMotionEvent(#)', type);

  final DeviceAcceleration acceleration;

  final DeviceAcceleration accelerationIncludingGravity;

  final num interval;

  final DeviceRotationRate rotationRate;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceOrientationEvent")
class DeviceOrientationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory DeviceOrientationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return DeviceOrientationEvent._create_1(type, eventInitDict_1);
    }
    return DeviceOrientationEvent._create_2(type);
  }
  static DeviceOrientationEvent _create_1(type, eventInitDict) => JS(
      'DeviceOrientationEvent',
      'new DeviceOrientationEvent(#,#)',
      type,
      eventInitDict);
  static DeviceOrientationEvent _create_2(type) =>
      JS('DeviceOrientationEvent', 'new DeviceOrientationEvent(#)', type);

  final bool absolute;

  final num alpha;

  final num beta;

  final num gamma;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceRotationRate")
class DeviceRotationRate extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() {
    throw new UnsupportedError("Not supported");
  }

  final num alpha;

  final num beta;

  final num gamma;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLDialogElement")
class DialogElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DialogElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DialogElement.created() : super.created();

  bool open;

  String returnValue;

  void close([String returnValue]) native;

  void show() native;

  void showModal() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryEntry")
class DirectoryEntry extends Entry {
  /**
   * Create a new directory with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a directory already
   * exists with the specified `path`.
   */
  Future<Entry> createDirectory(String path, {bool exclusive: false}) {
    return _getDirectory(path,
        options: {'create': true, 'exclusive': exclusive});
  }

  DirectoryReader createReader() {
    DirectoryReader reader = _createReader();
    applyExtension('DirectoryReader', reader);
    return reader;
  }

  /**
   * Retrieve an already existing directory entry. The returned future will
   * result in an error if a directory at `path` does not exist or if the item
   * at `path` is not a directory.
   */
  Future<Entry> getDirectory(String path) {
    return _getDirectory(path);
  }

  /**
   * Create a new file with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a file already
   * exists at the specified `path`.
   */
  Future<Entry> createFile(String path, {bool exclusive: false}) {
    return _getFile(path, options: {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing file entry. The returned future will
   * result in an error if a file at `path` does not exist or if the item at
   * `path` is not a file.
   */
  Future<Entry> getFile(String path) {
    return _getFile(path);
  }

  // To suppress missing implicit constructor warnings.
  factory DirectoryEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createReader')
  DirectoryReader _createReader() native;

  void __getDirectory(String path,
      [Map options,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_3(path, options_1);
      return;
    }
    __getDirectory_4(path);
    return;
  }

  @JSName('getDirectory')
  void __getDirectory_1(path, options, _EntryCallback successCallback,
      _ErrorCallback errorCallback) native;
  @JSName('getDirectory')
  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
  @JSName('getDirectory')
  void __getDirectory_3(path, options) native;
  @JSName('getDirectory')
  void __getDirectory_4(path) native;

  @JSName('getDirectory')
  Future<Entry> _getDirectory(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getDirectory(path, options, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  void __getFile(String path,
      [Map options,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_3(path, options_1);
      return;
    }
    __getFile_4(path);
    return;
  }

  @JSName('getFile')
  void __getFile_1(path, options, _EntryCallback successCallback,
      _ErrorCallback errorCallback) native;
  @JSName('getFile')
  void __getFile_2(path, options, _EntryCallback successCallback) native;
  @JSName('getFile')
  void __getFile_3(path, options) native;
  @JSName('getFile')
  void __getFile_4(path) native;

  @JSName('getFile')
  Future<Entry> _getFile(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getFile(path, options, (value) {
      applyExtension('FileEntry', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('removeRecursively')
  void _removeRecursively(VoidCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('removeRecursively')
  Future removeRecursively() {
    var completer = new Completer();
    _removeRecursively(() {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryReader")
class DirectoryReader extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('readEntries')
  void _readEntries(_EntriesCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  Future<List<Entry>> readEntries() {
    var completer = new Completer<List<Entry>>();
    _readEntries((values) {
      values.forEach((value) {
        applyExtension('Entry', value);
        Entry entry = value as Entry;
        if (entry.isFile)
          applyExtension('FileEntry', entry);
        else if (entry.isDirectory) applyExtension('DirectoryEntry', entry);
      });
      completer.complete(new List<Entry>.from(values));
    }, (error) {
      completer.completeError(error);
    });

    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A generic container for content on an HTML page;
 * corresponds to the &lt;div&gt; tag.
 *
 * The [DivElement] is a generic container and does not have any semantic
 * significance. It is functionally similar to [SpanElement].
 *
 * The [DivElement] is a block-level element, as opposed to [SpanElement],
 * which is an inline-level element.
 *
 * Example usage:
 *
 *     DivElement div = new DivElement();
 *     div.text = 'Here's my new DivElem
 *     document.body.elements.add(elem);
 *
 * See also:
 *
 * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
 * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
 * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
 */
@Native("HTMLDivElement")
class DivElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DivElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DivElement() => JS('returns:DivElement;creates:DivElement;new:true',
      '#.createElement(#)', document, "div");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DivElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * The base class for all documents.
 *
 * Each web page loaded in the browser has its own [Document] object, which is
 * typically an [HtmlDocument].
 *
 * If you aren't comfortable with DOM concepts, see the Dart tutorial
 * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
 */
@Native("Document")
class Document extends Node {
  // To suppress missing implicit constructor warnings.
  factory Document._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> pointerLockChangeEvent =
      const EventStreamProvider<Event>('pointerlockchange');

  static const EventStreamProvider<Event> pointerLockErrorEvent =
      const EventStreamProvider<Event>('pointerlockerror');

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> readyStateChangeEvent =
      const EventStreamProvider<Event>('readystatechange');

  /**
   * Static factory designed to expose `securitypolicyviolation` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SecurityPolicyViolationEvent>
      securityPolicyViolationEvent =
      const EventStreamProvider<SecurityPolicyViolationEvent>(
          'securitypolicyviolation');

  /**
   * Static factory designed to expose `selectionchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> selectionChangeEvent =
      const EventStreamProvider<Event>('selectionchange');

  factory Document() {
    return Document._create_1();
  }
  static Document _create_1() => JS('Document', 'new Document()');

  final String addressSpace;

  @JSName('body')
  HtmlElement _body;

  final String contentType;

  String cookie;

  final ScriptElement currentScript;

  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('defaultView')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  @Creates('Window|=Object|Null')
  @Returns('Window|=Object|Null')
  final dynamic _get_window;

  final Element documentElement;

  final String domain;

  final bool fullscreenEnabled;

  @JSName('head')
  final HeadElement _head;

  final bool hidden;

  final DomImplementation implementation;

  @JSName('lastModified')
  final String _lastModified;

  final String origin;

  @JSName('preferredStylesheetSet')
  final String _preferredStylesheetSet;

  final String readyState;

  @JSName('referrer')
  final String _referrer;

  final SvgSvgElement rootElement;

  Element rootScroller;

  final Element scrollingElement;

  @JSName('selectedStylesheetSet')
  String _selectedStylesheetSet;

  final String suborigin;

  final DocumentTimeline timeline;

  @JSName('title')
  String _title;

  @JSName('visibilityState')
  final String _visibilityState;

  @JSName('webkitFullscreenElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final Element _webkitFullscreenElement;

  @JSName('webkitFullscreenEnabled')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final bool _webkitFullscreenEnabled;

  @JSName('webkitHidden')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final bool _webkitHidden;

  @JSName('webkitVisibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final String _webkitVisibilityState;

  Node adoptNode(Node node) native;

  @JSName('caretRangeFromPoint')
  Range _caretRangeFromPoint(int x, int y) native;

  DocumentFragment createDocumentFragment() native;

  @JSName('createElement')
  Element _createElement(String localName_OR_tagName,
      [options_OR_typeExtension]) native;

  @JSName('createElementNS')
  Element _createElementNS(String namespaceURI, String qualifiedName,
      [options_OR_typeExtension]) native;

  @JSName('createEvent')
  Event _createEvent(String eventType) native;

  Range createRange() native;

  @JSName('createTextNode')
  Text _createTextNode(String data) native;

  Touch _createTouch(Window view, EventTarget target, int identifier, num pageX,
      num pageY, num screenX, num screenY,
      [num radiusX, num radiusY, num rotationAngle, num force]) {
    if (force != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_1(view, target_1, identifier, pageX, pageY, screenX,
          screenY, radiusX, radiusY, rotationAngle, force);
    }
    if (rotationAngle != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_2(view, target_1, identifier, pageX, pageY, screenX,
          screenY, radiusX, radiusY, rotationAngle);
    }
    if (radiusY != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_3(view, target_1, identifier, pageX, pageY, screenX,
          screenY, radiusX, radiusY);
    }
    if (radiusX != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_4(
          view, target_1, identifier, pageX, pageY, screenX, screenY, radiusX);
    }
    var target_1 = _convertDartToNative_EventTarget(target);
    return _createTouch_5(
        view, target_1, identifier, pageX, pageY, screenX, screenY);
  }

  @JSName('createTouch')
  Touch _createTouch_1(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX, radiusY, rotationAngle, force) native;
  @JSName('createTouch')
  Touch _createTouch_2(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX, radiusY, rotationAngle) native;
  @JSName('createTouch')
  Touch _createTouch_3(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX, radiusY) native;
  @JSName('createTouch')
  Touch _createTouch_4(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX) native;
  @JSName('createTouch')
  Touch _createTouch_5(
      Window view, target, identifier, pageX, pageY, screenX, screenY) native;

  @JSName('createTouchList')
  TouchList _createTouchList(Touch touches) native;

  bool execCommand(String commandId, [bool showUI, String value]) native;

  void exitFullscreen() native;

  void exitPointerLock() native;

  List<Animation> getAnimations() native;

  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByName(String elementName) native;

  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String localName) native;

  Node importNode(Node node, [bool deep]) native;

  bool queryCommandEnabled(String commandId) native;

  bool queryCommandIndeterm(String commandId) native;

  bool queryCommandState(String commandId) native;

  bool queryCommandSupported(String commandId) native;

  String queryCommandValue(String commandId) native;

  Function registerElement2(String type, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _registerElement2_1(type, options_1);
    }
    return _registerElement2_2(type);
  }

  @JSName('registerElement')
  Function _registerElement2_1(type, options) native;
  @JSName('registerElement')
  Function _registerElement2_2(type) native;

  @JSName('webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitExitFullscreen() native;

  // From NonElementParentNode

  Element getElementById(String elementId) native;

  // From DocumentOrShadowRoot

  final Element activeElement;

  final Element fullscreenElement;

  final Element pointerLockElement;

  @JSName('styleSheets')
  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> _styleSheets;

  @JSName('elementFromPoint')
  Element _elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  // From FontFaceSource

  final FontFaceSet fonts;

  // From ParentNode

  @JSName('childElementCount')
  final int _childElementCount;

  @JSName('children')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  final Element _firstElementChild;

  @JSName('lastElementChild')
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this document that matches the
   * specified group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelector]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = document.querySelector('.className');
   *     var element2 = document.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  /// Stream of `abort` events handled by this [Document].
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `beforecopy` events handled by this [Document].
  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);

  /// Stream of `beforecut` events handled by this [Document].
  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);

  /// Stream of `beforepaste` events handled by this [Document].
  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Document].
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  Stream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Document].
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Document].
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Document].
  Stream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent.forTarget(this);

  /// Stream of `copy` events handled by this [Document].
  Stream<ClipboardEvent> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  Stream<ClipboardEvent> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  Stream<Event> get onDurationChange =>
      Element.durationChangeEvent.forTarget(this);

  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Document].
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Document].
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  Stream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  Stream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  Stream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  Stream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  Stream<ClipboardEvent> get onPaste => Element.pasteEvent.forTarget(this);

  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  Stream<Event> get onPointerLockChange =>
      pointerLockChangeEvent.forTarget(this);

  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation =>
      securityPolicyViolationEvent.forTarget(this);

  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  Stream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  Stream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent.forTarget(this);

  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  Stream<Event> get onFullscreenChange =>
      Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  Stream<Event> get onFullscreenError =>
      Element.fullscreenErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
    return JS('bool', '("registerElement" in #)', this);
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  void registerElement(String tag, Type customElementClass,
      {String extendsTag}) {
    registerElement2(
        tag, {'prototype': customElementClass, 'extends': extendsTag});
  }

  @pragma('dart2js:tryInline') // Almost all call sites have one argument.
  Element createElement(String tagName, [String typeExtension]) {
    return (typeExtension == null)
        ? _createElement_2(tagName)
        : _createElement(tagName, typeExtension);
  }

  // The two-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  _createElement_2(String tagName) =>
      JS('Element', '#.createElement(#)', this, tagName);

  // The three-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  _createElementNS_2(String namespaceURI, String qualifiedName) => JS(
      'Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);

  Element createElementNS(String namespaceURI, String qualifiedName,
      [String typeExtension]) {
    return (typeExtension == null)
        ? _createElementNS_2(namespaceURI, qualifiedName)
        : _createElementNS(namespaceURI, qualifiedName, typeExtension);
  }

  NodeIterator _createNodeIterator(Node root,
          [int whatToShow, NodeFilter filter]) =>
      JS('NodeIterator', '#.createNodeIterator(#, #, #, false)', this, root,
          whatToShow, filter);

  TreeWalker _createTreeWalker(Node root,
          [int whatToShow, NodeFilter filter]) =>
      JS('TreeWalker', '#.createTreeWalker(#, #, #, false)', this, root,
          whatToShow, filter);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  String get visibilityState => JS(
      'String',
      '(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
      '#.webkitVisibilityState)',
      this,
      this,
      this,
      this);
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DocumentFragment")
class DocumentFragment extends Node
    implements NonElementParentNode, ParentNode {
  factory DocumentFragment() => document.createDocumentFragment();

  factory DocumentFragment.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    return document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  factory DocumentFragment.svg(String svgContent,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    return new svg.SvgSvgElement().createFragment(svgContent,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  HtmlCollection get _children =>
      throw new UnimplementedError('Use _docChildren instead');

  // Native field is used only by Dart code so does not lead to instantiation
  // of native classes
  @Creates('Null')
  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));

  String get innerHtml {
    final e = new DivElement();
    e.append(this.clone(true));
    return e.innerHtml;
  }

  set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.nodes.clear();
    append(document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.append(new DocumentFragment.html(text,
        validator: validator, treeSanitizer: treeSanitizer));
  }

  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() {
    throw new UnsupportedError("Not supported");
  }

  // From NonElementParentNode

  Element getElementById(String elementId) native;

  // From ParentNode

  @JSName('childElementCount')
  final int _childElementCount;

  @JSName('firstElementChild')
  final Element _firstElementChild;

  @JSName('lastElementChild')
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this document fragment that matches
   * the specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = fragment.querySelector('.className');
   *     var element2 = fragment.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DocumentOrShadowRoot")
class DocumentOrShadowRoot extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DocumentOrShadowRoot._() {
    throw new UnsupportedError("Not supported");
  }

  final Element activeElement;

  final Element fullscreenElement;

  final Element pointerLockElement;

  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> styleSheets;

  Element elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  Selection getSelection() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DocumentTimeline")
class DocumentTimeline extends AnimationTimeline {
  // To suppress missing implicit constructor warnings.
  factory DocumentTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  factory DocumentTimeline([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return DocumentTimeline._create_1(options_1);
    }
    return DocumentTimeline._create_2();
  }
  static DocumentTimeline _create_1(options) =>
      JS('DocumentTimeline', 'new DocumentTimeline(#)', options);
  static DocumentTimeline _create_2() =>
      JS('DocumentTimeline', 'new DocumentTimeline()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMError")
class DomError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomError._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomError(String name, [String message]) {
    if (message != null) {
      return DomError._create_1(name, message);
    }
    return DomError._create_2(name);
  }
  static DomError _create_1(name, message) =>
      JS('DomError', 'new DOMError(#,#)', name, message);
  static DomError _create_2(name) => JS('DomError', 'new DOMError(#)', name);

  final String message;

  final String name;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("DOMException")
class DomException extends Interceptor {
  static const String INDEX_SIZE = 'IndexSizeError';
  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
  static const String WRONG_DOCUMENT = 'WrongDocumentError';
  static const String INVALID_CHARACTER = 'InvalidCharacterError';
  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
  static const String NOT_FOUND = 'NotFoundError';
  static const String NOT_SUPPORTED = 'NotSupportedError';
  static const String INVALID_STATE = 'InvalidStateError';
  static const String SYNTAX = 'SyntaxError';
  static const String INVALID_MODIFICATION = 'InvalidModificationError';
  static const String NAMESPACE = 'NamespaceError';
  static const String INVALID_ACCESS = 'InvalidAccessError';
  static const String TYPE_MISMATCH = 'TypeMismatchError';
  static const String SECURITY = 'SecurityError';
  static const String NETWORK = 'NetworkError';
  static const String ABORT = 'AbortError';
  static const String URL_MISMATCH = 'URLMismatchError';
  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
  static const String TIMEOUT = 'TimeoutError';
  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
  static const String DATA_CLONE = 'DataCloneError';
  // Is TypeError class derived from DomException but name is 'TypeError'
  static const String TYPE_ERROR = 'TypeError';

  String get name {
    var errorName = JS('String', '#.name', this);
    // Although Safari nightly has updated the name to SecurityError, Safari 5
    // and 6 still return SECURITY_ERR.
    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
    // Chrome release still uses old string, remove this line when Chrome stable
    // also prints out SyntaxError.
    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
    return errorName;
  }

  // To suppress missing implicit constructor warnings.
  factory DomException._() {
    throw new UnsupportedError("Not supported");
  }

  final String message;

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMImplementation")
class DomImplementation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomImplementation._() {
    throw new UnsupportedError("Not supported");
  }

  XmlDocument createDocument(
      String namespaceURI, String qualifiedName, _DocumentType doctype) native;

  _DocumentType createDocumentType(
      String qualifiedName, String publicId, String systemId) native;

  @JSName('createHTMLDocument')
  HtmlDocument createHtmlDocument([String title]) native;

  bool hasFeature() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Iterator")
class DomIterator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomIterator._() {
    throw new UnsupportedError("Not supported");
  }

  Object next([Object value]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMMatrix")
class DomMatrix extends DomMatrixReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomMatrix._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomMatrix([Object init]) {
    if (init != null) {
      return DomMatrix._create_1(init);
    }
    return DomMatrix._create_2();
  }
  static DomMatrix _create_1(init) => JS('DomMatrix', 'new DOMMatrix(#)', init);
  static DomMatrix _create_2() => JS('DomMatrix', 'new DOMMatrix()');

  // Shadowing definition.
  num get a => JS("num", "#.a", this);

  set a(num value) {
    JS("void", "#.a = #", this, value);
  }

  // Shadowing definition.
  num get b => JS("num", "#.b", this);

  set b(num value) {
    JS("void", "#.b = #", this, value);
  }

  // Shadowing definition.
  num get c => JS("num", "#.c", this);

  set c(num value) {
    JS("void", "#.c = #", this, value);
  }

  // Shadowing definition.
  num get d => JS("num", "#.d", this);

  set d(num value) {
    JS("void", "#.d = #", this, value);
  }

  // Shadowing definition.
  num get e => JS("num", "#.e", this);

  set e(num value) {
    JS("void", "#.e = #", this, value);
  }

  // Shadowing definition.
  num get f => JS("num", "#.f", this);

  set f(num value) {
    JS("void", "#.f = #", this, value);
  }

  // Shadowing definition.
  num get m11 => JS("num", "#.m11", this);

  set m11(num value) {
    JS("void", "#.m11 = #", this, value);
  }

  // Shadowing definition.
  num get m12 => JS("num", "#.m12", this);

  set m12(num value) {
    JS("void", "#.m12 = #", this, value);
  }

  // Shadowing definition.
  num get m13 => JS("num", "#.m13", this);

  set m13(num value) {
    JS("void", "#.m13 = #", this, value);
  }

  // Shadowing definition.
  num get m14 => JS("num", "#.m14", this);

  set m14(num value) {
    JS("void", "#.m14 = #", this, value);
  }

  // Shadowing definition.
  num get m21 => JS("num", "#.m21", this);

  set m21(num value) {
    JS("void", "#.m21 = #", this, value);
  }

  // Shadowing definition.
  num get m22 => JS("num", "#.m22", this);

  set m22(num value) {
    JS("void", "#.m22 = #", this, value);
  }

  // Shadowing definition.
  num get m23 => JS("num", "#.m23", this);

  set m23(num value) {
    JS("void", "#.m23 = #", this, value);
  }

  // Shadowing definition.
  num get m24 => JS("num", "#.m24", this);

  set m24(num value) {
    JS("void", "#.m24 = #", this, value);
  }

  // Shadowing definition.
  num get m31 => JS("num", "#.m31", this);

  set m31(num value) {
    JS("void", "#.m31 = #", this, value);
  }

  // Shadowing definition.
  num get m32 => JS("num", "#.m32", this);

  set m32(num value) {
    JS("void", "#.m32 = #", this, value);
  }

  // Shadowing definition.
  num get m33 => JS("num", "#.m33", this);

  set m33(num value) {
    JS("void", "#.m33 = #", this, value);
  }

  // Shadowing definition.
  num get m34 => JS("num", "#.m34", this);

  set m34(num value) {
    JS("void", "#.m34 = #", this, value);
  }

  // Shadowing definition.
  num get m41 => JS("num", "#.m41", this);

  set m41(num value) {
    JS("void", "#.m41 = #", this, value);
  }

  // Shadowing definition.
  num get m42 => JS("num", "#.m42", this);

  set m42(num value) {
    JS("void", "#.m42 = #", this, value);
  }

  // Shadowing definition.
  num get m43 => JS("num", "#.m43", this);

  set m43(num value) {
    JS("void", "#.m43 = #", this, value);
  }

  // Shadowing definition.
  num get m44 => JS("num", "#.m44", this);

  set m44(num value) {
    JS("void", "#.m44 = #", this, value);
  }

  static DomMatrix fromFloat32Array(Float32List array32) native;

  static DomMatrix fromFloat64Array(Float64List array64) native;

  static DomMatrix fromMatrix([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromMatrix_1(other_1);
    }
    return _fromMatrix_2();
  }

  @JSName('fromMatrix')
  static DomMatrix _fromMatrix_1(other) native;
  @JSName('fromMatrix')
  static DomMatrix _fromMatrix_2() native;

  DomMatrix invertSelf() native;

  DomMatrix multiplySelf([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _multiplySelf_1(other_1);
    }
    return _multiplySelf_2();
  }

  @JSName('multiplySelf')
  DomMatrix _multiplySelf_1(other) native;
  @JSName('multiplySelf')
  DomMatrix _multiplySelf_2() native;

  DomMatrix preMultiplySelf([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _preMultiplySelf_1(other_1);
    }
    return _preMultiplySelf_2();
  }

  @JSName('preMultiplySelf')
  DomMatrix _preMultiplySelf_1(other) native;
  @JSName('preMultiplySelf')
  DomMatrix _preMultiplySelf_2() native;

  DomMatrix rotateAxisAngleSelf([num x, num y, num z, num angle]) native;

  DomMatrix rotateFromVectorSelf([num x, num y]) native;

  DomMatrix rotateSelf([num rotX, num rotY, num rotZ]) native;

  DomMatrix scale3dSelf([num scale, num originX, num originY, num originZ])
      native;

  DomMatrix scaleSelf(
      [num scaleX,
      num scaleY,
      num scaleZ,
      num originX,
      num originY,
      num originZ]) native;

  DomMatrix setMatrixValue(String transformList) native;

  DomMatrix skewXSelf([num sx]) native;

  DomMatrix skewYSelf([num sy]) native;

  DomMatrix translateSelf([num tx, num ty, num tz]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMMatrixReadOnly")
class DomMatrixReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomMatrixReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomMatrixReadOnly([Object init]) {
    if (init != null) {
      return DomMatrixReadOnly._create_1(init);
    }
    return DomMatrixReadOnly._create_2();
  }
  static DomMatrixReadOnly _create_1(init) =>
      JS('DomMatrixReadOnly', 'new DOMMatrixReadOnly(#)', init);
  static DomMatrixReadOnly _create_2() =>
      JS('DomMatrixReadOnly', 'new DOMMatrixReadOnly()');

  num get a => JS("num", "#.a", this);

  num get b => JS("num", "#.b", this);

  num get c => JS("num", "#.c", this);

  num get d => JS("num", "#.d", this);

  num get e => JS("num", "#.e", this);

  num get f => JS("num", "#.f", this);

  bool get is2D => JS("bool", "#.is2D", this);

  bool get isIdentity => JS("bool", "#.isIdentity", this);

  num get m11 => JS("num", "#.m11", this);

  num get m12 => JS("num", "#.m12", this);

  num get m13 => JS("num", "#.m13", this);

  num get m14 => JS("num", "#.m14", this);

  num get m21 => JS("num", "#.m21", this);

  num get m22 => JS("num", "#.m22", this);

  num get m23 => JS("num", "#.m23", this);

  num get m24 => JS("num", "#.m24", this);

  num get m31 => JS("num", "#.m31", this);

  num get m32 => JS("num", "#.m32", this);

  num get m33 => JS("num", "#.m33", this);

  num get m34 => JS("num", "#.m34", this);

  num get m41 => JS("num", "#.m41", this);

  num get m42 => JS("num", "#.m42", this);

  num get m43 => JS("num", "#.m43", this);

  num get m44 => JS("num", "#.m44", this);

  DomMatrix flipX() native;

  DomMatrix flipY() native;

  static DomMatrixReadOnly fromFloat32Array(Float32List array32) native;

  static DomMatrixReadOnly fromFloat64Array(Float64List array64) native;

  static DomMatrixReadOnly fromMatrix([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromMatrix_1(other_1);
    }
    return _fromMatrix_2();
  }

  @JSName('fromMatrix')
  static DomMatrixReadOnly _fromMatrix_1(other) native;
  @JSName('fromMatrix')
  static DomMatrixReadOnly _fromMatrix_2() native;

  DomMatrix inverse() native;

  DomMatrix multiply([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _multiply_1(other_1);
    }
    return _multiply_2();
  }

  @JSName('multiply')
  DomMatrix _multiply_1(other) native;
  @JSName('multiply')
  DomMatrix _multiply_2() native;

  DomMatrix rotate([num rotX, num rotY, num rotZ]) native;

  DomMatrix rotateAxisAngle([num x, num y, num z, num angle]) native;

  DomMatrix rotateFromVector([num x, num y]) native;

  DomMatrix scale(
      [num scaleX,
      num scaleY,
      num scaleZ,
      num originX,
      num originY,
      num originZ]) native;

  DomMatrix scale3d([num scale, num originX, num originY, num originZ]) native;

  DomMatrix skewX([num sx]) native;

  DomMatrix skewY([num sy]) native;

  Float32List toFloat32Array() native;

  Float64List toFloat64Array() native;

  DomPoint transformPoint([Map point]) {
    if (point != null) {
      var point_1 = convertDartToNative_Dictionary(point);
      return _transformPoint_1(point_1);
    }
    return _transformPoint_2();
  }

  @JSName('transformPoint')
  DomPoint _transformPoint_1(point) native;
  @JSName('transformPoint')
  DomPoint _transformPoint_2() native;

  DomMatrix translate([num tx, num ty, num tz]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMParser")
class DomParser extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomParser._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomParser() {
    return DomParser._create_1();
  }
  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');

  Document parseFromString(String str, String type) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMPoint")
class DomPoint extends DomPointReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomPoint._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomPoint([num x, num y, num z, num w]) {
    if (w != null) {
      return DomPoint._create_1(x, y, z, w);
    }
    if (z != null) {
      return DomPoint._create_2(x, y, z);
    }
    if (y != null) {
      return DomPoint._create_3(x, y);
    }
    if (x != null) {
      return DomPoint._create_4(x);
    }
    return DomPoint._create_5();
  }
  static DomPoint _create_1(x, y, z, w) =>
      JS('DomPoint', 'new DOMPoint(#,#,#,#)', x, y, z, w);
  static DomPoint _create_2(x, y, z) =>
      JS('DomPoint', 'new DOMPoint(#,#,#)', x, y, z);
  static DomPoint _create_3(x, y) => JS('DomPoint', 'new DOMPoint(#,#)', x, y);
  static DomPoint _create_4(x) => JS('DomPoint', 'new DOMPoint(#)', x);
  static DomPoint _create_5() => JS('DomPoint', 'new DOMPoint()');

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)');

  // Shadowing definition.
  num get w => JS("num", "#.w", this);

  set w(num value) {
    JS("void", "#.w = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }

  // Shadowing definition.
  num get z => JS("num", "#.z", this);

  set z(num value) {
    JS("void", "#.z = #", this, value);
  }

  static DomPoint fromPoint([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromPoint_1(other_1);
    }
    return _fromPoint_2();
  }

  @JSName('fromPoint')
  static DomPoint _fromPoint_1(other) native;
  @JSName('fromPoint')
  static DomPoint _fromPoint_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMPointReadOnly")
class DomPointReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomPointReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomPointReadOnly([num x, num y, num z, num w]) {
    if (w != null) {
      return DomPointReadOnly._create_1(x, y, z, w);
    }
    if (z != null) {
      return DomPointReadOnly._create_2(x, y, z);
    }
    if (y != null) {
      return DomPointReadOnly._create_3(x, y);
    }
    if (x != null) {
      return DomPointReadOnly._create_4(x);
    }
    return DomPointReadOnly._create_5();
  }
  static DomPointReadOnly _create_1(x, y, z, w) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#,#)', x, y, z, w);
  static DomPointReadOnly _create_2(x, y, z) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#)', x, y, z);
  static DomPointReadOnly _create_3(x, y) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#)', x, y);
  static DomPointReadOnly _create_4(x) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#)', x);
  static DomPointReadOnly _create_5() =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly()');

  num get w => JS("num", "#.w", this);

  num get x => JS("num", "#.x", this);

  num get y => JS("num", "#.y", this);

  num get z => JS("num", "#.z", this);

  static DomPointReadOnly fromPoint([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromPoint_1(other_1);
    }
    return _fromPoint_2();
  }

  @JSName('fromPoint')
  static DomPointReadOnly _fromPoint_1(other) native;
  @JSName('fromPoint')
  static DomPointReadOnly _fromPoint_2() native;

  DomPoint matrixTransform([Map matrix]) {
    if (matrix != null) {
      var matrix_1 = convertDartToNative_Dictionary(matrix);
      return _matrixTransform_1(matrix_1);
    }
    return _matrixTransform_2();
  }

  @JSName('matrixTransform')
  DomPoint _matrixTransform_1(matrix) native;
  @JSName('matrixTransform')
  DomPoint _matrixTransform_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMQuad")
class DomQuad extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomQuad._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomQuad([Map p1, Map p2, Map p3, Map p4]) {
    if (p4 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      var p2_2 = convertDartToNative_Dictionary(p2);
      var p3_3 = convertDartToNative_Dictionary(p3);
      var p4_4 = convertDartToNative_Dictionary(p4);
      return DomQuad._create_1(p1_1, p2_2, p3_3, p4_4);
    }
    if (p3 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      var p2_2 = convertDartToNative_Dictionary(p2);
      var p3_3 = convertDartToNative_Dictionary(p3);
      return DomQuad._create_2(p1_1, p2_2, p3_3);
    }
    if (p2 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      var p2_2 = convertDartToNative_Dictionary(p2);
      return DomQuad._create_3(p1_1, p2_2);
    }
    if (p1 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      return DomQuad._create_4(p1_1);
    }
    return DomQuad._create_5();
  }
  static DomQuad _create_1(p1, p2, p3, p4) =>
      JS('DomQuad', 'new DOMQuad(#,#,#,#)', p1, p2, p3, p4);
  static DomQuad _create_2(p1, p2, p3) =>
      JS('DomQuad', 'new DOMQuad(#,#,#)', p1, p2, p3);
  static DomQuad _create_3(p1, p2) => JS('DomQuad', 'new DOMQuad(#,#)', p1, p2);
  static DomQuad _create_4(p1) => JS('DomQuad', 'new DOMQuad(#)', p1);
  static DomQuad _create_5() => JS('DomQuad', 'new DOMQuad()');

  final DomPoint p1;

  final DomPoint p2;

  final DomPoint p3;

  final DomPoint p4;

  static DomQuad fromQuad([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromQuad_1(other_1);
    }
    return _fromQuad_2();
  }

  @JSName('fromQuad')
  static DomQuad _fromQuad_1(other) native;
  @JSName('fromQuad')
  static DomQuad _fromQuad_2() native;

  static DomQuad fromRect([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromRect_1(other_1);
    }
    return _fromRect_2();
  }

  @JSName('fromRect')
  static DomQuad _fromRect_1(other) native;
  @JSName('fromRect')
  static DomQuad _fromRect_2() native;

  Rectangle getBounds() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ClientRectList,DOMRectList")
class DomRectList extends Interceptor
    with ListMixin<Rectangle>, ImmutableListMixin<Rectangle>
    implements List<Rectangle>, JavaScriptIndexingBehavior<Rectangle> {
  // To suppress missing implicit constructor warnings.
  factory DomRectList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Rectangle operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Rectangle", "#[#]", this, index);
  }

  void operator []=(int index, Rectangle value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Rectangle> mixins.
  // Rectangle is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Rectangle get first {
    if (this.length > 0) {
      return JS('Rectangle', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Rectangle get last {
    int len = this.length;
    if (len > 0) {
      return JS('Rectangle', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Rectangle get single {
    int len = this.length;
    if (len == 1) {
      return JS('Rectangle', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Rectangle elementAt(int index) => this[index];
  // -- end List<Rectangle> mixins.

  Rectangle item(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMRectReadOnly")
class DomRectReadOnly extends Interceptor implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight =>
      new Point(this.left + this.width, this.top + this.height);
  Point get bottomLeft => new Point(this.left, this.top + this.height);

  // To suppress missing implicit constructor warnings.
  factory DomRectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomRectReadOnly([num x, num y, num width, num height]) {
    if (height != null) {
      return DomRectReadOnly._create_1(x, y, width, height);
    }
    if (width != null) {
      return DomRectReadOnly._create_2(x, y, width);
    }
    if (y != null) {
      return DomRectReadOnly._create_3(x, y);
    }
    if (x != null) {
      return DomRectReadOnly._create_4(x);
    }
    return DomRectReadOnly._create_5();
  }
  static DomRectReadOnly _create_1(x, y, width, height) => JS(
      'DomRectReadOnly', 'new DOMRectReadOnly(#,#,#,#)', x, y, width, height);
  static DomRectReadOnly _create_2(x, y, width) =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#,#)', x, y, width);
  static DomRectReadOnly _create_3(x, y) =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#)', x, y);
  static DomRectReadOnly _create_4(x) =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly(#)', x);
  static DomRectReadOnly _create_5() =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly()');

  num get bottom => JS("num", "#.bottom", this);

  num get height => JS("num", "#.height", this);

  num get left => JS("num", "#.left", this);

  num get right => JS("num", "#.right", this);

  num get top => JS("num", "#.top", this);

  num get width => JS("num", "#.width", this);

  num get x => JS("num", "#.x", this);

  num get y => JS("num", "#.y", this);

  static DomRectReadOnly fromRect([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromRect_1(other_1);
    }
    return _fromRect_2();
  }

  @JSName('fromRect')
  static DomRectReadOnly _fromRect_1(other) native;
  @JSName('fromRect')
  static DomRectReadOnly _fromRect_2() native;
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMStringList")
class DomStringList extends Interceptor
    with ListMixin<String>, ImmutableListMixin<String>
    implements JavaScriptIndexingBehavior<String>, List<String> {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  String operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("String", "#[#]", this, index);
  }

  void operator []=(int index, String value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<String> mixins.
  // String is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  String get first {
    if (this.length > 0) {
      return JS('String', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  String get last {
    int len = this.length;
    if (len > 0) {
      return JS('String', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  String get single {
    int len = this.length;
    if (len == 1) {
      return JS('String', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  String elementAt(int index) => this[index];
  // -- end List<String> mixins.

  String item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMStringMap")
class DomStringMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomStringMap._() {
    throw new UnsupportedError("Not supported");
  }

  void __delete__(String name) native;

  void __setter__(String name, String value) native;

  String item(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMTokenList")
class DomTokenList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  String value;

  void add(String tokens) native;

  bool contains(String token) native;

  String item(int index) native;

  void remove(String tokens) native;

  void replace(String token, String newToken) native;

  bool supports(String token) native;

  bool toggle(String token, [bool force]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
      : _childElements = element._children,
        _element = element;

  bool contains(Object element) => _childElements.contains(element);

  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(Element element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void removeRange(int start, int end) {
    throw new UnimplementedError();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
      [int skipCount = 0]) {
    throw new UnimplementedError();
  }

  bool remove(Object object) {
    if (object is Element) {
      Element element = object;
      if (identical(element.parentNode, _element)) {
        _element._removeChild(element);
        return true;
      }
    }
    return false;
  }

  void insert(int index, Element element) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _element.append(element);
    } else {
      _element.insertBefore(element, this[index]);
    }
  }

  void setAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void clear() {
    _element._clearChildren();
  }

  Element removeAt(int index) {
    final result = this[index];
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element removeLast() {
    final result = this.last;
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element get first {
    Element result = _element._firstElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get last {
    Element result = _element._lastElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get single {
    if (length > 1) throw new StateError("More than one element");
    return first;
  }

  List<Node> get rawList => _childElements;
}

/**
 * An immutable list containing HTML elements. This list contains some
 * additional methods when compared to regular lists for ease of CSS
 * manipulation on a group of elements.
 */
abstract class ElementList<T extends Element> extends ListBase<T> {
  /**
   * The union of all CSS classes applied to the elements in this list.
   *
   * This set makes it easy to add, remove or toggle (add if not present, remove
   * if present) the classes applied to a collection of elements.
   *
   *     htmlList.classes.add('selected');
   *     htmlList.classes.toggle('isOnline');
   *     htmlList.classes.remove('selected');
   */
  CssClassSet get classes;

  /** Replace the classes with `value` for every element in this list. */
  set classes(Iterable<String> value);

  /**
   * Access the union of all [CssStyleDeclaration]s that are associated with an
   * [ElementList].
   *
   * Grouping the style objects all together provides easy editing of specific
   * properties of a collection of elements. Setting a specific property value
   * will set that property in all [Element]s in the [ElementList]. Getting a
   * specific property value will return the value of the property of the first
   * element in the [ElementList].
   */
  CssStyleDeclarationBase get style;

  /**
   * Access dimensions and position of the Elements in this list.
   *
   * Setting the height or width properties will set the height or width
   * property for all elements in the list. This returns a rectangle with the
   * dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Getting the height or width returns the height or width of the
   * first Element in this list.
   *
   * Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   */
  CssRect get contentEdge;

  /**
   * Access dimensions and position of the first Element's content + padding box
   * in this list.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `innerHeight` value for an element. This
   * is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   */
  CssRect get paddingEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border box in this list.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  CssRect get borderEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border + margin box in this list.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  CssRect get marginEdge;

  /// Stream of `abort` events handled by this [Element].
  ElementStream<Event> get onAbort;

  /// Stream of `beforecopy` events handled by this [Element].
  ElementStream<Event> get onBeforeCopy;

  /// Stream of `beforecut` events handled by this [Element].
  ElementStream<Event> get onBeforeCut;

  /// Stream of `beforepaste` events handled by this [Element].
  ElementStream<Event> get onBeforePaste;

  /// Stream of `blur` events handled by this [Element].
  ElementStream<Event> get onBlur;

  ElementStream<Event> get onCanPlay;

  ElementStream<Event> get onCanPlayThrough;

  /// Stream of `change` events handled by this [Element].
  ElementStream<Event> get onChange;

  /// Stream of `click` events handled by this [Element].
  ElementStream<MouseEvent> get onClick;

  /// Stream of `contextmenu` events handled by this [Element].
  ElementStream<MouseEvent> get onContextMenu;

  /// Stream of `copy` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrop;

  ElementStream<Event> get onDurationChange;

  ElementStream<Event> get onEmptied;

  ElementStream<Event> get onEnded;

  /// Stream of `error` events handled by this [Element].
  ElementStream<Event> get onError;

  /// Stream of `focus` events handled by this [Element].
  ElementStream<Event> get onFocus;

  /// Stream of `input` events handled by this [Element].
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyUp;

  /// Stream of `load` events handled by this [Element].
  ElementStream<Event> get onLoad;

  ElementStream<Event> get onLoadedData;

  ElementStream<Event> get onLoadedMetadata;

  /// Stream of `mousedown` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  ElementStream<ClipboardEvent> get onPaste;

  ElementStream<Event> get onPause;

  ElementStream<Event> get onPlay;

  ElementStream<Event> get onPlaying;

  ElementStream<Event> get onRateChange;

  /// Stream of `reset` events handled by this [Element].
  ElementStream<Event> get onReset;

  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  ElementStream<Event> get onSearch;

  ElementStream<Event> get onSeeked;

  ElementStream<Event> get onSeeking;

  /// Stream of `select` events handled by this [Element].
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  ElementStream<Event> get onSelectStart;

  ElementStream<Event> get onStalled;

  /// Stream of `submit` events handled by this [Element].
  ElementStream<Event> get onSubmit;

  ElementStream<Event> get onSuspend;

  ElementStream<Event> get onTimeUpdate;

  /// Stream of `touchcancel` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  ElementStream<Event> get onVolumeChange;

  ElementStream<Event> get onWaiting;

  /// Stream of `fullscreenchange` events handled by this [Element].
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  ElementStream<Event> get onFullscreenError;

  ElementStream<WheelEvent> get onWheel;
}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList<E extends Element> extends ListBase<E>
    implements ElementList<E>, NodeListWrapper {
  final List<Node> _nodeList;

  _FrozenElementList._wrap(this._nodeList) {
    assert(this._nodeList.every((element) => element is E),
        "Query expects only HTML elements of type $E but found ${this._nodeList.firstWhere((e) => e is! E)}");
  }

  int get length => _nodeList.length;

  E operator [](int index) => _nodeList[index];

  void operator []=(int index, E value) {
    throw new UnsupportedError('Cannot modify list');
  }

  set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<E> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  E get first => _nodeList.first;

  E get last => _nodeList.last;

  E get single => _nodeList.single;

  CssClassSet get classes => new _MultiElementCssClassSet(this);

  CssStyleDeclarationBase get style => new _CssStyleDeclarationSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): This might be faster for Sets:
    //
    //     new _MultiElementCssClassSet(this).writeClasses(value)
    //
    // as the code below converts the Iterable[value] to a string multiple
    // times.  Maybe compute the string and set className here.
    forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.first.marginEdge;

  List<Node> get rawList => _nodeList;

  /// Stream of `abort` events handled by this [Element].
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  ElementStream<Event> get onBeforeCopy =>
      Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  ElementStream<Event> get onBeforeCut =>
      Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  ElementStream<Event> get onBeforePaste =>
      Element.beforePasteEvent._forElementList(this);

  /// Stream of `blur` events handled by this [Element].
  ElementStream<Event> get onBlur => Element.blurEvent._forElementList(this);

  ElementStream<Event> get onCanPlay =>
      Element.canPlayEvent._forElementList(this);

  ElementStream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  ElementStream<Event> get onChange =>
      Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  ElementStream<MouseEvent> get onClick =>
      Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  ElementStream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCopy =>
      Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCut =>
      Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  ElementStream<Event> get onDoubleClick =>
      Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrag =>
      Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnd =>
      Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnter =>
      Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragLeave =>
      Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragOver =>
      Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragStart =>
      Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrop =>
      Element.dropEvent._forElementList(this);

  ElementStream<Event> get onDurationChange =>
      Element.durationChangeEvent._forElementList(this);

  ElementStream<Event> get onEmptied =>
      Element.emptiedEvent._forElementList(this);

  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);

  /// Stream of `error` events handled by this [Element].
  ElementStream<Event> get onError => Element.errorEvent._forElementList(this);

  /// Stream of `focus` events handled by this [Element].
  ElementStream<Event> get onFocus => Element.focusEvent._forElementList(this);

  /// Stream of `input` events handled by this [Element].
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  ElementStream<Event> get onInvalid =>
      Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyDown =>
      Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyPress =>
      Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyUp =>
      Element.keyUpEvent._forElementList(this);

  /// Stream of `load` events handled by this [Element].
  ElementStream<Event> get onLoad => Element.loadEvent._forElementList(this);

  ElementStream<Event> get onLoadedData =>
      Element.loadedDataEvent._forElementList(this);

  ElementStream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseDown =>
      Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseMove =>
      Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOut =>
      Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOver =>
      Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseUp =>
      Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  ElementStream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  ElementStream<ClipboardEvent> get onPaste =>
      Element.pasteEvent._forElementList(this);

  ElementStream<Event> get onPause => Element.pauseEvent._forElementList(this);

  ElementStream<Event> get onPlay => Element.playEvent._forElementList(this);

  ElementStream<Event> get onPlaying =>
      Element.playingEvent._forElementList(this);

  ElementStream<Event> get onRateChange =>
      Element.rateChangeEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  ElementStream<Event> get onResize =>
      Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  ElementStream<Event> get onScroll =>
      Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  ElementStream<Event> get onSearch =>
      Element.searchEvent._forElementList(this);

  ElementStream<Event> get onSeeked =>
      Element.seekedEvent._forElementList(this);

  ElementStream<Event> get onSeeking =>
      Element.seekingEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  ElementStream<Event> get onSelect =>
      Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  ElementStream<Event> get onSelectStart =>
      Element.selectStartEvent._forElementList(this);

  ElementStream<Event> get onStalled =>
      Element.stalledEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  ElementStream<Event> get onSubmit =>
      Element.submitEvent._forElementList(this);

  ElementStream<Event> get onSuspend =>
      Element.suspendEvent._forElementList(this);

  ElementStream<Event> get onTimeUpdate =>
      Element.timeUpdateEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnd =>
      Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnter =>
      Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchLeave =>
      Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchMove =>
      Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd =>
      Element.transitionEndEvent._forElementList(this);

  ElementStream<Event> get onVolumeChange =>
      Element.volumeChangeEvent._forElementList(this);

  ElementStream<Event> get onWaiting =>
      Element.waitingEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  ElementStream<Event> get onFullscreenChange =>
      Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  ElementStream<Event> get onFullscreenError =>
      Element.fullscreenErrorEvent._forElementList(this);

  ElementStream<WheelEvent> get onWheel =>
      Element.wheelEvent._forElementList(this);
}

/**
 * An abstract class, which all HTML elements extend.
 */
@Native("Element")
class Element extends Node
    implements
        NonDocumentTypeChildNode,
        GlobalEventHandlers,
        ParentNode,
        ChildNode {
  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created();

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is better to use the element type constructors:
   *
   *     var element = new DivElement();
   *
   * It is better to use e.g `new CanvasElement()` because the type of the
   * expression is `CanvasElement`, whereas the type of `Element.tag` is the
   * less specific `Element`.
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is equivalent to calling `new Element.tag('a')`.
  factory Element.a() => new AnchorElement();

  /// Creates a new `<article>` element.
  ///
  /// This is equivalent to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is equivalent to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is equivalent to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is equivalent to calling `new Element.tag('br')`.
  factory Element.br() => new BRElement();

  /// Creates a new `<canvas>` element.
  ///
  /// This is equivalent to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new CanvasElement();

  /// Creates a new `<div>` element.
  ///
  /// This is equivalent to calling `new Element.tag('div')`.
  factory Element.div() => new DivElement();

  /// Creates a new `<footer>` element.
  ///
  /// This is equivalent to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is equivalent to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is equivalent to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is equivalent to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is equivalent to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is equivalent to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is equivalent to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is equivalent to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is equivalent to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is equivalent to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is equivalent to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is equivalent to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is equivalent to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is equivalent to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is equivalent to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is equivalent to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is equivalent to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is equivalent to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is equivalent to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is equivalent to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is equivalent to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is equivalent to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  @pragma('dart2js:tryInline')
  String getAttribute(String name) {
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    return _getAttribute(name);
  }

  @pragma('dart2js:tryInline')
  String getAttributeNS(String namespaceURI, String name) {
    // Protect [name] against string conversion to "null" or "undefined".
    // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
    assert(name != null, 'Attribute name cannot be null');
    return _getAttributeNS(namespaceURI, name);
  }

  @pragma('dart2js:tryInline')
  bool hasAttribute(String name) {
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    return _hasAttribute(name);
  }

  @pragma('dart2js:tryInline')
  bool hasAttributeNS(String namespaceURI, String name) {
    // Protect [name] against string conversion to "null" or "undefined".
    // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
    assert(name != null, 'Attribute name cannot be null');
    return _hasAttributeNS(namespaceURI, name);
  }

  @pragma('dart2js:tryInline')
  void removeAttribute(String name) {
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    _removeAttribute(name);
  }

  @pragma('dart2js:tryInline')
  void removeAttributeNS(String namespaceURI, String name) {
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    _removeAttributeNS(namespaceURI, name);
  }

  @pragma('dart2js:tryInline')
  void setAttribute(String name, String value) {
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
    _setAttribute(name, value);
  }

  @pragma('dart2js:tryInline')
  void setAttributeNS(String namespaceURI, String name, String value) {
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
    _setAttributeNS(namespaceURI, name, value);
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));

  @JSName('setApplyScroll')
  void _setApplyScroll(ScrollStateCallback scrollStateCallback,
      String nativeScrollBehavior) native;

  Future<ScrollState> setApplyScroll(String nativeScrollBehavior) {
    var completer = new Completer<ScrollState>();
    _setApplyScroll((value) {
      completer.complete(value);
    }, nativeScrollBehavior);
    return completer.future;
  }

  @JSName('setDistributeScroll')
  void _setDistributeScroll(ScrollStateCallback scrollStateCallback,
      String nativeScrollBehavior) native;

  Future<ScrollState> setDistributeScroll(String nativeScrollBehavior) {
    var completer = new Completer<ScrollState>();
    _setDistributeScroll((value) {
      completer.complete(value);
    }, nativeScrollBehavior);
    return completer.future;
  }

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): Do this without reading the classes in clear() and addAll(),
    // or writing the classes in clear().
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data
   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset => new _DataAttributeMap(attributes);

  set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [Cascade and Inheritance](https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance)
   *   from MDN.
   * * [Pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
   *   from MDN.
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client =>
      new Rectangle(clientLeft, clientTop, clientWidth, clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset =>
      new Rectangle(offsetLeft, offsetTop, offsetWidth, offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.insertAdjacentHtml('beforeend', text,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @deprecated
  void enteredView() {}

  List<Rectangle> getClientRects() {
    var value = _getClientRects();

    // If no prototype we need one for the world to hookup to the proper Dart class.
    var jsProto = JS('', '#.prototype', value);
    if (jsProto == null) {
      JS('', '#.prototype = Object.create(null)', value);
    }

    applyExtension('DOMRectList', value);

    return value;
  }

  /** *Deprecated*: override [detached] instead. */
  @deprecated
  void leftView() {}

  /**
   * Creates a new AnimationEffect object whose target element is the object
   * on which the method is called, and calls the play() method of the
   * AnimationTimeline object of the document timeline of the node document
   * of the element, passing the newly created AnimationEffect as the argument
   * to the method. Returns an Animation for the effect.
   *
   * Examples
   *
   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
   *
   *     var animation = elem.animate([
   *       {"transform": "translate(100px, -100%)"},
   *       {"transform" : "translate(400px, 500px)"}
   *     ], 1500);
   *
   * The [frames] parameter is an Iterable<Map>, where the
   * map entries specify CSS animation effects. The
   * [timing] paramter can be a double, representing the number of milliseconds
   * for the transition, or a Map with fields corresponding to those
   * of the [Timing] object.
  **/
  @SupportedBrowser(SupportedBrowser.CHROME, '36')
  Animation animate(Iterable<Map<String, dynamic>> frames, [timing]) {
    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
      throw new ArgumentError("The frames parameter should be a List of Maps "
          "with frame information");
    }
    var convertedFrames;
    if (frames is Iterable) {
      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
    } else {
      convertedFrames = frames;
    }
    var convertedTiming =
        timing is Map ? convertDartToNative_Dictionary(timing) : timing;
    return convertedTiming == null
        ? _animate(convertedFrames)
        : _animate(convertedFrames, convertedTiming);
  }

  @JSName('animate')
  Animation _animate(Object effect, [timing]) native;
  /**
   * Called by the DOM whenever an attribute on this has been changed.
   */
  void attributeChanged(String name, String oldValue, String newValue) {}

  @Returns('String')
  // Non-null for Elements.
  String get localName => JS('String', '#', _localName);

  /**
   * A URI that identifies the XML namespace of this element.
   *
   * `null` if no namespace URI is specified.
   *
   * ## Other resources
   *
   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
   *   from W3C.
   */
  String get namespaceUri => _namespaceUri;

  /**
   * The string representation of this element.
   *
   * This is equivalent to reading the [localName] property.
   */
  String toString() => localName;

  /**
   * Scrolls this element into view.
   *
   * Only one of of the alignment options may be specified at a time.
   *
   * If no options are specified then this will attempt to scroll the minimum
   * amount needed to bring the element into view.
   *
   * Note that alignCenter is currently only supported on WebKit platforms. If
   * alignCenter is specified but not supported then this will fall back to
   * alignTop.
   *
   * See also:
   *
   * * [scrollIntoView](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView)
   *   from MDN.
   * * [scrollIntoViewIfNeeded](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded)
   *   from MDN.
   */
  void scrollIntoView([ScrollAlignment alignment]) {
    var hasScrollIntoViewIfNeeded = true;
    hasScrollIntoViewIfNeeded =
        JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
    if (alignment == ScrollAlignment.TOP) {
      this._scrollIntoView(true);
    } else if (alignment == ScrollAlignment.BOTTOM) {
      this._scrollIntoView(false);
    } else if (hasScrollIntoViewIfNeeded) {
      if (alignment == ScrollAlignment.CENTER) {
        this._scrollIntoViewIfNeeded(true);
      } else {
        this._scrollIntoViewIfNeeded();
      }
    } else {
      this._scrollIntoView();
    }
  }

  /**
   * Static factory designed to expose `mousewheel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const _CustomEventStreamProvider<WheelEvent>(
          Element._determineMouseWheelEventType);

  static String _determineMouseWheelEventType(EventTarget e) => 'wheel';

  /**
   * Static factory designed to expose `transitionend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TransitionEvent> transitionEndEvent =
      const _CustomEventStreamProvider<TransitionEvent>(
          Element._determineTransitionEventType);

  static String _determineTransitionEventType(EventTarget e) {
    // Unfortunately the normal 'ontransitionend' style checks don't work here.
    if (Device.isWebKit) {
      return 'webkitTransitionEnd';
    } else if (Device.isOpera) {
      return 'oTransitionEnd';
    }
    return 'transitionend';
  }

  /**
   * Inserts text into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  void insertAdjacentText(String where, String text) {
    if (JS('bool', '!!#.insertAdjacentText', this)) {
      _insertAdjacentText(where, text);
    } else {
      _insertAdjacentNode(where, new Text(text));
    }
  }

  @JSName('insertAdjacentText')
  void _insertAdjacentText(String where, String text) native;

  /**
   * Parses text as an HTML fragment and inserts it into the DOM at the
   * specified location.
   *
   * The [where] parameter indicates where to insert the HTML fragment:
   *
   * * 'beforeBegin': Immediately before this element.
   * * 'afterBegin': As the first child of this element.
   * * 'beforeEnd': As the last child of this element.
   * * 'afterEnd': Immediately after this element.
   *
   *     var html = '<div class="something">content</div>';
   *     // Inserts as the first child
   *     document.body.insertAdjacentHtml('afterBegin', html);
   *     var createdElement = document.body.children[0];
   *     print(createdElement.classes[0]); // Prints 'something'
   *
   * See also:
   *
   * * [insertAdjacentText]
   * * [insertAdjacentElement]
   */
  void insertAdjacentHtml(String where, String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _insertAdjacentHtml(where, html);
    } else {
      _insertAdjacentNode(
          where,
          createFragment(html,
              validator: validator, treeSanitizer: treeSanitizer));
    }
  }

  @JSName('insertAdjacentHTML')
  void _insertAdjacentHtml(String where, String text) native;

  /**
   * Inserts [element] into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  Element insertAdjacentElement(String where, Element element) {
    if (JS('bool', '!!#.insertAdjacentElement', this)) {
      _insertAdjacentElement(where, element);
    } else {
      _insertAdjacentNode(where, element);
    }
    return element;
  }

  @JSName('insertAdjacentElement')
  void _insertAdjacentElement(String where, Element element) native;

  void _insertAdjacentNode(String where, Node node) {
    switch (where.toLowerCase()) {
      case 'beforebegin':
        this.parentNode.insertBefore(node, this);
        break;
      case 'afterbegin':
        var first = this.nodes.length > 0 ? this.nodes[0] : null;
        this.insertBefore(node, first);
        break;
      case 'beforeend':
        this.append(node);
        break;
      case 'afterend':
        this.parentNode.insertBefore(node, this.nextNode);
        break;
      default:
        throw new ArgumentError("Invalid position ${where}");
    }
  }

  /**
   * Checks if this element matches the CSS selectors.
   */
  bool matches(String selectors) {
    if (JS('bool', '!!#.matches', this)) {
      return JS('bool', '#.matches(#)', this, selectors);
    } else if (JS('bool', '!!#.webkitMatchesSelector', this)) {
      return JS('bool', '#.webkitMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.mozMatchesSelector', this)) {
      return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.msMatchesSelector', this)) {
      return JS('bool', '#.msMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
    } else {
      throw new UnsupportedError("Not supported on this platform");
    }
  }

  /** Checks if this element or any of its parents match the CSS selectors. */
  bool matchesWithAncestors(String selectors) {
    var elem = this;
    do {
      if (elem.matches(selectors)) return true;
      elem = elem.parent;
    } while (elem != null);
    return false;
  }

  /**
   * Creates a new shadow root for this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   *   from HTML5Rocks.
   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  ShadowRoot createShadowRoot() {
    return JS(
        'ShadowRoot',
        '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)',
        this,
        this,
        this);
  }

  /**
   * The shadow root of this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   *   from HTML5Rocks.
   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
   *   from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  ShadowRoot get shadowRoot =>
      JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this);

  /**
   * Access this element's content position.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get contentEdge => new _ContentCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding box.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
   * This is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get paddingEdge => new _PaddingCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border box.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get borderEdge => new _BorderCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border + margin box.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method will perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get marginEdge => new _MarginCssRect(this);

  /**
   * Provides the coordinates of the element relative to the top of the
   * document.
   *
   * This method is the Dart equivalent to jQuery's
   * [offset](http://api.jquery.com/offset/) method.
   */
  Point get documentOffset => offsetTo(document.documentElement);

  /**
   * Provides the offset of this element's [borderEdge] relative to the
   * specified [parent].
   *
   * This is the Dart equivalent of jQuery's
   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
   * position, however, [parent] can be any parent element of `this`,
   * rather than only `this`'s immediate [offsetParent]. If the specified
   * element is _not_ an offset parent or transitive offset parent to this
   * element, an [ArgumentError] is thrown.
   */
  Point offsetTo(Element parent) {
    return Element._offsetToHelper(this, parent);
  }

  static Point _offsetToHelper(Element current, Element parent) {
    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
    // offsetParent, "tops out" at BODY. But people could conceivably pass in
    // the document.documentElement and I want it to return an absolute offset,
    // so we have the special case checking for HTML.
    bool sameAsParent = identical(current, parent);
    bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
    if (current == null || sameAsParent) {
      if (foundAsParent) return new Point(0, 0);
      throw new ArgumentError("Specified element is not a transitive offset "
          "parent of this element.");
    }
    Element parentOffset = current.offsetParent;
    Point p = Element._offsetToHelper(parentOffset, parent);
    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Safari bug. Was also previously Chrome bug 229142
      // - URIs are not resolved in new doc.
      BaseElement base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }

    // TODO(terry): Fixes Chromium 50 change no body after createHtmlDocument()
    if (_parseDocument.body == null) {
      _parseDocument.body = _parseDocument.createElement("body");
    }

    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment &&
        _canBeUsedToCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /** Test if createContextualFragment is supported for this element type */
  bool get _canBeUsedToCreateContextualFragment =>
      !_cannotBeUsedToCreateContextualFragment;

  /** Test if createContextualFragment is NOT supported for this element type */
  bool get _cannotBeUsedToCreateContextualFragment =>
      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);

  /**
   * A hard-coded list of the tag names for which createContextualFragment
   * isn't supported.
   */
  static const _tagsForWhichCreateContextualFragmentIsNotSupported = const [
    'HEAD',
    'AREA',
    'BASE',
    'BASEFONT',
    'BR',
    'COL',
    'COLGROUP',
    'EMBED',
    'FRAME',
    'FRAMESET',
    'HR',
    'IMAGE',
    'IMG',
    'INPUT',
    'ISINDEX',
    'LINK',
    'META',
    'PARAM',
    'SOURCE',
    'STYLE',
    'TITLE',
    'WBR'
  ];

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _innerHtml = html;
    } else {
      append(createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer));
    }
  }

  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  /**
   * Verify if any of the attributes that we use in the sanitizer look unexpected,
   * possibly indicating DOM clobbering attacks.
   *
   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
   */
  static bool _hasCorruptedAttributes(Element element) {
    return JS(
        'bool',
        r'''
       (function(element) {
         if (!(element.attributes instanceof NamedNodeMap)) {
	   return true;
	 }
	 var childNodes = element.childNodes;
	 if (element.lastChild &&
	     element.lastChild !== childNodes[childNodes.length -1]) {
	   return true;
	 }
	 if (element.children) { // On Safari, children can apparently be null.
  	   if (!((element.children instanceof HTMLCollection) ||
               (element.children instanceof NodeList))) {
	     return true;
	   }
	 }
         var length = 0;
         if (element.children) {
           length = element.children.length;
         }
         for (var i = 0; i < length; i++) {
           var child = element.children[i];
           // On IE it seems like we sometimes don't see the clobbered attribute,
           // perhaps as a result of an over-optimization. Also use another route
           // to check of attributes, children, or lastChild are clobbered. It may
           // seem silly to check children as we rely on children to do this iteration,
           // but it seems possible that the access to children might see the real thing,
           // allowing us to check for clobbering that may show up in other accesses.
           if (child["id"] == 'attributes' || child["name"] == 'attributes' ||
               child["id"] == 'lastChild'  || child["name"] == 'lastChild' ||
               child["id"] == 'children' || child["name"] == 'children') {
             return true;
           }
         }
	 return false;
          })(#)''',
        element);
  }

  /// A secondary check for corruption, needed on IE
  static bool _hasCorruptedAttributesAdditionalCheck(Element element) {
    return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element);
  }

  static String _safeTagName(element) {
    String result = 'element tag unavailable';
    try {
      if (element.tagName is String) {
        result = element.tagName;
      }
    } catch (e) {}
    return result;
  }

  final Element offsetParent;

  int get offsetHeight => JS('num', '#.offsetHeight', this).round();

  int get offsetLeft => JS('num', '#.offsetLeft', this).round();

  int get offsetTop => JS('num', '#.offsetTop', this).round();

  int get offsetWidth => JS('num', '#.offsetWidth', this).round();

  int get scrollHeight => JS('num', '#.scrollHeight', this).round();
  int get scrollLeft => JS('num', '#.scrollLeft', this).round();

  set scrollLeft(int value) {
    JS("void", "#.scrollLeft = #", this, value.round());
  }

  int get scrollTop => JS('num', '#.scrollTop', this).round();

  set scrollTop(int value) {
    JS("void", "#.scrollTop = #", this, value.round());
  }

  int get scrollWidth => JS('num', '#.scrollWidth', this).round();

  // To suppress missing implicit constructor warnings.
  factory Element._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  /**
   * Static factory designed to expose `beforecopy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> beforeCopyEvent =
      const EventStreamProvider<Event>('beforecopy');

  /**
   * Static factory designed to expose `beforecut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> beforeCutEvent =
      const EventStreamProvider<Event>('beforecut');

  /**
   * Static factory designed to expose `beforepaste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> beforePasteEvent =
      const EventStreamProvider<Event>('beforepaste');

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  static const EventStreamProvider<Event> canPlayEvent =
      const EventStreamProvider<Event>('canplay');

  static const EventStreamProvider<Event> canPlayThroughEvent =
      const EventStreamProvider<Event>('canplaythrough');

  /**
   * Static factory designed to expose `change` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> clickEvent =
      const EventStreamProvider<MouseEvent>('click');

  /**
   * Static factory designed to expose `contextmenu` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> contextMenuEvent =
      const EventStreamProvider<MouseEvent>('contextmenu');

  /**
   * Static factory designed to expose `copy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ClipboardEvent> copyEvent =
      const EventStreamProvider<ClipboardEvent>('copy');

  /**
   * Static factory designed to expose `cut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ClipboardEvent> cutEvent =
      const EventStreamProvider<ClipboardEvent>('cut');

  /**
   * Static factory designed to expose `doubleclick` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.dblclickEvent')
  static const EventStreamProvider<Event> doubleClickEvent =
      const EventStreamProvider<Event>('dblclick');

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragEvent =
      const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragEndEvent =
      const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragEnterEvent =
      const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
      const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragOverEvent =
      const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragStartEvent =
      const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dropEvent =
      const EventStreamProvider<MouseEvent>('drop');

  static const EventStreamProvider<Event> durationChangeEvent =
      const EventStreamProvider<Event>('durationchange');

  static const EventStreamProvider<Event> emptiedEvent =
      const EventStreamProvider<Event>('emptied');

  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `input` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> inputEvent =
      const EventStreamProvider<Event>('input');

  /**
   * Static factory designed to expose `invalid` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> invalidEvent =
      const EventStreamProvider<Event>('invalid');

  /**
   * Static factory designed to expose `keydown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
      const EventStreamProvider<KeyboardEvent>('keydown');

  /**
   * Static factory designed to expose `keypress` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
      const EventStreamProvider<KeyboardEvent>('keypress');

  /**
   * Static factory designed to expose `keyup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
      const EventStreamProvider<KeyboardEvent>('keyup');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  static const EventStreamProvider<Event> loadedDataEvent =
      const EventStreamProvider<Event>('loadeddata');

  static const EventStreamProvider<Event> loadedMetadataEvent =
      const EventStreamProvider<Event>('loadedmetadata');

  /**
   * Static factory designed to expose `mousedown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseDownEvent =
      const EventStreamProvider<MouseEvent>('mousedown');

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
      const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
      const EventStreamProvider<MouseEvent>('mouseleave');

  /**
   * Static factory designed to expose `mousemove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
      const EventStreamProvider<MouseEvent>('mousemove');

  /**
   * Static factory designed to expose `mouseout` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseOutEvent =
      const EventStreamProvider<MouseEvent>('mouseout');

  /**
   * Static factory designed to expose `mouseover` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseOverEvent =
      const EventStreamProvider<MouseEvent>('mouseover');

  /**
   * Static factory designed to expose `mouseup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseUpEvent =
      const EventStreamProvider<MouseEvent>('mouseup');

  /**
   * Static factory designed to expose `paste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ClipboardEvent> pasteEvent =
      const EventStreamProvider<ClipboardEvent>('paste');

  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  static const EventStreamProvider<Event> playEvent =
      const EventStreamProvider<Event>('play');

  static const EventStreamProvider<Event> playingEvent =
      const EventStreamProvider<Event>('playing');

  static const EventStreamProvider<Event> rateChangeEvent =
      const EventStreamProvider<Event>('ratechange');

  /**
   * Static factory designed to expose `reset` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> resetEvent =
      const EventStreamProvider<Event>('reset');

  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  /**
   * Static factory designed to expose `scroll` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> searchEvent =
      const EventStreamProvider<Event>('search');

  static const EventStreamProvider<Event> seekedEvent =
      const EventStreamProvider<Event>('seeked');

  static const EventStreamProvider<Event> seekingEvent =
      const EventStreamProvider<Event>('seeking');

  /**
   * Static factory designed to expose `select` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> selectEvent =
      const EventStreamProvider<Event>('select');

  /**
   * Static factory designed to expose `selectstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> selectStartEvent =
      const EventStreamProvider<Event>('selectstart');

  static const EventStreamProvider<Event> stalledEvent =
      const EventStreamProvider<Event>('stalled');

  /**
   * Static factory designed to expose `submit` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> submitEvent =
      const EventStreamProvider<Event>('submit');

  static const EventStreamProvider<Event> suspendEvent =
      const EventStreamProvider<Event>('suspend');

  static const EventStreamProvider<Event> timeUpdateEvent =
      const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchCancelEvent =
      const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchEndEvent =
      const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchEnterEvent =
      const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchLeaveEvent =
      const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchMoveEvent =
      const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchStartEvent =
      const EventStreamProvider<TouchEvent>('touchstart');

  static const EventStreamProvider<Event> volumeChangeEvent =
      const EventStreamProvider<Event>('volumechange');

  static const EventStreamProvider<Event> waitingEvent =
      const EventStreamProvider<Event>('waiting');

  /**
   * Static factory designed to expose `fullscreenchange` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<Event> fullscreenChangeEvent =
      const EventStreamProvider<Event>('webkitfullscreenchange');

  /**
   * Static factory designed to expose `fullscreenerror` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<Event> fullscreenErrorEvent =
      const EventStreamProvider<Event>('webkitfullscreenerror');

  static const EventStreamProvider<WheelEvent> wheelEvent =
      const EventStreamProvider<WheelEvent>('wheel');

  String contentEditable;

  String dir;

  /**
   * Indicates whether the element can be dragged and dropped.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  bool draggable;

  /**
   * Indicates whether the element is not relevant to the page's current state.
   *
   * ## Other resources
   *
   * * [Hidden attribute
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
   *   from WHATWG.
   */
  bool hidden;

  bool inert;

  String inputMode;

  // Using property as subclass shadows.
  bool get isContentEditable => JS("bool", "#.isContentEditable", this);

  String lang;

  bool spellcheck;

  final CssStyleDeclaration style;

  int tabIndex;

  String title;

  /**
   * Specifies whether this element's text content changes when the page is
   * localized.
   *
   * ## Other resources
   *
   * * [The translate
   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)
   *   from WHATWG.
   */
  bool translate;

  void blur() native;

  void click() native;

  void focus() native;

  final AccessibleNode accessibleNode;

  final SlotElement assignedSlot;

  @JSName('attributes')
  final _NamedNodeMap _attributes;

  String className;

  final int clientHeight;

  final int clientLeft;

  final int clientTop;

  final int clientWidth;

  final String computedName;

  final String computedRole;

  String id;

  @JSName('innerHTML')
  String _innerHtml;

  @JSName('localName')
  final String _localName;

  @JSName('namespaceURI')
  final String _namespaceUri;

  // Using property as subclass shadows.
  String get outerHtml => JS("String", "#.outerHTML", this);

  @JSName('scrollHeight')
  final int _scrollHeight;

  @JSName('scrollLeft')
  num _scrollLeft;

  @JSName('scrollTop')
  num _scrollTop;

  @JSName('scrollWidth')
  final int _scrollWidth;

  String slot;

  final StylePropertyMap styleMap;

  final String tagName;

  ShadowRoot attachShadow(Map shadowRootInitDict) {
    var shadowRootInitDict_1 =
        convertDartToNative_Dictionary(shadowRootInitDict);
    return _attachShadow_1(shadowRootInitDict_1);
  }

  @JSName('attachShadow')
  ShadowRoot _attachShadow_1(shadowRootInitDict) native;

  Element closest(String selectors) native;

  List<Animation> getAnimations() native;

  @JSName('getAttribute')
  String _getAttribute(String name) native;

  @JSName('getAttributeNS')
  String _getAttributeNS(String namespaceURI, String localName) native;

  List<String> getAttributeNames() native;

  /**
   * Returns the smallest bounding rectangle that encompasses this element's
   * padding, scrollbar, and border.
   *
   * ## Other resources
   *
   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
   *   from MDN.
   * * [The getBoundingClientRect()
   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
   *   from W3C.
   */
  @Creates('_DomRect')
  @Returns('_DomRect|Null')
  Rectangle getBoundingClientRect() native;

  @JSName('getClientRects')
  /**
   * Returns a list of bounding rectangles for each box associated with this
   * element.
   *
   * ## Other resources
   *
   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
   *   from MDN.
   * * [The getClientRects()
   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
   *   from W3C.
   */
  @Creates('DomRectList')
  @Returns('DomRectList|Null')
  List<Rectangle> _getClientRects() native;

  /**
   * Returns a list of shadow DOM insertion points to which this element is
   * distributed.
   *
   * ## Other resources
   *
   * * [Shadow DOM
   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
   *   from W3C.
   */
  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  /**
   * Returns a list of nodes with the given class name inside this element.
   *
   * ## Other resources
   *
   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
   *   from MDN.
   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
   */
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @JSName('getElementsByTagName')
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> _getElementsByTagName(String localName) native;

  @JSName('hasAttribute')
  bool _hasAttribute(String name) native;

  @JSName('hasAttributeNS')
  bool _hasAttributeNS(String namespaceURI, String localName) native;

  bool hasPointerCapture(int pointerId) native;

  void releasePointerCapture(int pointerId) native;

  @JSName('removeAttribute')
  void _removeAttribute(String name) native;

  @JSName('removeAttributeNS')
  void _removeAttributeNS(String namespaceURI, String localName) native;

  void requestPointerLock() native;

  void scroll([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scroll_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scroll_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scroll_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scroll')
  void _scroll_1() native;
  @JSName('scroll')
  void _scroll_2(options) native;
  @JSName('scroll')
  void _scroll_3(num x, y) native;

  void scrollBy([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scrollBy_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollBy_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scrollBy_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollBy')
  void _scrollBy_1() native;
  @JSName('scrollBy')
  void _scrollBy_2(options) native;
  @JSName('scrollBy')
  void _scrollBy_3(num x, y) native;

  @JSName('scrollIntoView')
  void _scrollIntoView([Object arg]) native;

  @JSName('scrollIntoViewIfNeeded')
  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native;

  void scrollTo([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scrollTo_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollTo_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scrollTo_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollTo')
  void _scrollTo_1() native;
  @JSName('scrollTo')
  void _scrollTo_2(options) native;
  @JSName('scrollTo')
  void _scrollTo_3(num x, y) native;

  @JSName('setAttribute')
  void _setAttribute(String name, String value) native;

  @JSName('setAttributeNS')
  void _setAttributeNS(String namespaceURI, String name, String value) native;

  void setPointerCapture(int pointerId) native;

  @JSName('webkitRequestFullscreen')
  /**
   * Displays this element fullscreen.
   *
   * ## Other resources
   *
   * * [Fullscreen
   *   API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)
   *   from MDN.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void requestFullscreen() native;

  // From ChildNode

  void after(Object nodes) native;

  void before(Object nodes) native;

  // From NonDocumentTypeChildNode

  final Element nextElementSibling;

  final Element previousElementSibling;

  // From ParentNode

  @JSName('childElementCount')
  final int _childElementCount;

  @JSName('children')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  final Element _firstElementChild;

  @JSName('lastElementChild')
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this element that matches the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     // Gets the first descendant with the class 'classname'
   *     var element = element.querySelector('.className');
   *     // Gets the element with id 'id'
   *     var element = element.querySelector('#id');
   *     // Gets the first descendant [ImageElement]
   *     var img = element.querySelector('img');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  /// Stream of `abort` events handled by this [Element].
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  /// Stream of `beforecopy` events handled by this [Element].
  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);

  /// Stream of `beforecut` events handled by this [Element].
  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);

  /// Stream of `beforepaste` events handled by this [Element].
  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);

  /// Stream of `blur` events handled by this [Element].
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  ElementStream<Event> get onCanPlayThrough =>
      canPlayThroughEvent.forElement(this);

  /// Stream of `change` events handled by this [Element].
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  /// Stream of `click` events handled by this [Element].
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  /// Stream of `contextmenu` events handled by this [Element].
  ElementStream<MouseEvent> get onContextMenu =>
      contextMenuEvent.forElement(this);

  /// Stream of `copy` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  ElementStream<Event> get onDurationChange =>
      durationChangeEvent.forElement(this);

  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  /// Stream of `error` events handled by this [Element].
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [Element].
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `input` events handled by this [Element].
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  /// Stream of `load` events handled by this [Element].
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  ElementStream<Event> get onLoadedMetadata =>
      loadedMetadataEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseEnter =>
      mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseLeave =>
      mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  ElementStream<WheelEvent> get onMouseWheel =>
      mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  ElementStream<ClipboardEvent> get onPaste => pasteEvent.forElement(this);

  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  ElementStream<Event> get onPlay => playEvent.forElement(this);

  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchCancel =>
      touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnter =>
      touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchLeave =>
      touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchStart =>
      touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd =>
      transitionEndEvent.forElement(this);

  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  ElementStream<Event> get onFullscreenChange =>
      fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  ElementStream<Event> get onFullscreenError =>
      fullscreenErrorEvent.forElement(this);

  ElementStream<WheelEvent> get onWheel => wheelEvent.forElement(this);
}

class _ElementFactoryProvider {
  // Optimization to improve performance until the dart2js compiler inlines this
  // method.
  static dynamic createElement_tag(String tag, String typeExtension) {
    // Firefox may return a JS function for some types (Embed, Object).
    if (typeExtension != null) {
      return JS('Element|=Object', 'document.createElement(#, #)', tag,
          typeExtension);
    }
    // Should be able to eliminate this and just call the two-arg version above
    // with null typeExtension, but Chrome treats the tag as case-sensitive if
    // typeExtension is null.
    // https://code.google.com/p/chromium/issues/detail?id=282467
    return JS('Element|=Object', 'document.createElement(#)', tag);
  }
}

/**
 * Options for Element.scrollIntoView.
 */
class ScrollAlignment {
  final _value;
  const ScrollAlignment._internal(this._value);
  toString() => 'ScrollAlignment.$_value';

  /// Attempt to align the element to the top of the scrollable area.
  static const TOP = const ScrollAlignment._internal('TOP');

  /// Attempt to center the element in the scrollable area.
  static const CENTER = const ScrollAlignment._internal('CENTER');

  /// Attempt to align the element to the bottom of the scrollable area.
  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLEmbedElement")
class EmbedElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory EmbedElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory EmbedElement() => document.createElement("embed");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  EmbedElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('embed');

  String height;

  String name;

  String src;

  String type;

  String width;

  Node __getter__(String name) native;

  void __setter__(String name, Node value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _EntriesCallback(List entries);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Entry")
class Entry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Entry._() {
    throw new UnsupportedError("Not supported");
  }

  final FileSystem filesystem;

  final String fullPath;

  final bool isDirectory;

  final bool isFile;

  final String name;

  @JSName('copyTo')
  void _copyTo(DirectoryEntry parent,
      [String name,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('copyTo')
  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _copyTo(parent, name, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('getMetadata')
  void _getMetadata(MetadataCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('getMetadata')
  Future<Metadata> getMetadata() {
    var completer = new Completer<Metadata>();
    _getMetadata((value) {
      applyExtension('Metadata', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('getParent')
  void _getParent(
      [_EntryCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('getParent')
  Future<Entry> getParent() {
    var completer = new Completer<Entry>();
    _getParent((value) {
      applyExtension('Entry', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('moveTo')
  void _moveTo(DirectoryEntry parent,
      [String name,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('moveTo')
  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _moveTo(parent, name, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('remove')
  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback])
      native;

  @JSName('remove')
  Future remove() {
    var completer = new Completer();
    _remove(() {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('toURL')
  String toUrl() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _EntryCallback(Entry entry);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _ErrorCallback(DomException error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("ErrorEvent")
class ErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ErrorEvent._create_1(type, eventInitDict_1);
    }
    return ErrorEvent._create_2(type);
  }
  static ErrorEvent _create_1(type, eventInitDict) =>
      JS('ErrorEvent', 'new ErrorEvent(#,#)', type, eventInitDict);
  static ErrorEvent _create_2(type) =>
      JS('ErrorEvent', 'new ErrorEvent(#)', type);

  final int colno;

  @Creates('Null')
  final Object error;

  final String filename;

  final int lineno;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("Event,InputEvent")
class Event extends Interceptor {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type, {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type,
        canBubble: canBubble, cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name,
      {bool canBubble: true, bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }

  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    Element currentTarget = this.currentTarget;
    Element target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  List<EventTarget> get path =>
      JS('bool', '!!#.composedPath', this) ? composedPath() : [];

  factory Event._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return Event._create_1(type, eventInitDict_1);
    }
    return Event._create_2(type);
  }
  static Event _create_1(type, eventInitDict) =>
      JS('Event', 'new Event(#,#)', type, eventInitDict);
  static Event _create_2(type) => JS('Event', 'new Event(#)', type);

  /**
   * This event is being handled by the event target.
   *
   * ## Other resources
   *
   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
   *   from W3C.
   */
  static const int AT_TARGET = 2;

  /**
   * This event is bubbling up through the target's ancestors.
   *
   * ## Other resources
   *
   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   *   from W3C.
   */
  static const int BUBBLING_PHASE = 3;

  /**
   * This event is propagating through the target's ancestors, starting from the
   * document.
   *
   * ## Other resources
   *
   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   *   from W3C.
   */
  static const int CAPTURING_PHASE = 1;

  final bool bubbles;

  final bool cancelable;

  final bool composed;

  EventTarget get currentTarget =>
      _convertNativeToDart_EventTarget(this._get_currentTarget);
  @JSName('currentTarget')
  @Creates('Null')
  @Returns('EventTarget|=Object|Null')
  final dynamic _get_currentTarget;

  final bool defaultPrevented;

  final int eventPhase;

  final bool isTrusted;

  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_target;

  final num timeStamp;

  final String type;

  List<EventTarget> composedPath() native;

  @JSName('initEvent')
  void _initEvent(String type, [bool bubbles, bool cancelable]) native;

  void preventDefault() native;

  void stopImmediatePropagation() native;

  void stopPropagation() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("EventSource")
class EventSource extends EventTarget {
  factory EventSource(String url, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(url, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  static EventSource _factoryEventSource(String url,
      [Map eventSourceInitDict]) {
    if (eventSourceInitDict != null) {
      var eventSourceInitDict_1 =
          convertDartToNative_Dictionary(eventSourceInitDict);
      return EventSource._create_1(url, eventSourceInitDict_1);
    }
    return EventSource._create_2(url);
  }

  static EventSource _create_1(url, eventSourceInitDict) =>
      JS('EventSource', 'new EventSource(#,#)', url, eventSourceInitDict);
  static EventSource _create_2(url) =>
      JS('EventSource', 'new EventSource(#)', url);

  static const int CLOSED = 2;

  static const int CONNECTING = 0;

  static const int OPEN = 1;

  final int readyState;

  final String url;

  final bool withCredentials;

  void close() native;

  /// Stream of `error` events handled by this [EventSource].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [EventSource].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [EventSource].
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Base class that supports listening for and dispatching browser events.
 *
 * Normally events are accessed via the Stream getter:
 *
 *     element.onMouseOver.listen((e) => print('Mouse over!'));
 *
 * To access bubbling events which are declared on one element, but may bubble
 * up to another element type (common for MediaElement events):
 *
 *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
 *
 * To useCapture on events:
 *
 *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
 *
 * Custom events can be declared as:
 *
 *     class DataGenerator {
 *       static EventStreamProvider<Event> dataEvent =
 *           new EventStreamProvider('data');
 *     }
 *
 * Then listeners should access the event with:
 *
 *     DataGenerator.dataEvent.forTarget(element).listen(...);
 *
 * Custom events can also be accessed as:
 *
 *     element.on['some_event'].listen(...);
 *
 * This approach is generally discouraged as it loses the event typing and
 * some DOM events may have multiple platform-dependent event names under the
 * covers. By using the standard Stream getters you will get the platform
 * specific event name automatically.
 */
class Events {
  /* Raw event target. */
  final EventTarget _ptr;

  Events(this._ptr);

  Stream<Event> operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  static final webkitEvents = {
    'animationend': 'webkitAnimationEnd',
    'animationiteration': 'webkitAnimationIteration',
    'animationstart': 'webkitAnimationStart',
    'fullscreenchange': 'webkitfullscreenchange',
    'fullscreenerror': 'webkitfullscreenerror',
    'keyadded': 'webkitkeyadded',
    'keyerror': 'webkitkeyerror',
    'keymessage': 'webkitkeymessage',
    'needkey': 'webkitneedkey',
    'pointerlockchange': 'webkitpointerlockchange',
    'pointerlockerror': 'webkitpointerlockerror',
    'resourcetimingbufferfull': 'webkitresourcetimingbufferfull',
    'transitionend': 'webkitTransitionEnd',
    'speechchange': 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : super(ptr);

  Stream<Event> operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@Native("EventTarget")
class EventTarget extends Interceptor {
  // Custom element created callback.
  EventTarget._created();

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  Events get on => new Events(this);

  void addEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _addEventListener(type, listener, useCapture);
    }
  }

  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _removeEventListener(type, listener, useCapture);
    }
  }

  // To suppress missing implicit constructor warnings.
  factory EventTarget._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('addEventListener')
  void _addEventListener(String type, EventListener listener, [bool options])
      native;

  bool dispatchEvent(Event event) native;

  @JSName('removeEventListener')
  void _removeEventListener(String type, EventListener listener, [bool options])
      native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ExtendableEvent")
class ExtendableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ExtendableEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ExtendableEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ExtendableEvent._create_1(type, eventInitDict_1);
    }
    return ExtendableEvent._create_2(type);
  }
  static ExtendableEvent _create_1(type, eventInitDict) =>
      JS('ExtendableEvent', 'new ExtendableEvent(#,#)', type, eventInitDict);
  static ExtendableEvent _create_2(type) =>
      JS('ExtendableEvent', 'new ExtendableEvent(#)', type);

  void waitUntil(Future f) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ExtendableMessageEvent")
class ExtendableMessageEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ExtendableMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final Object data;

  final String lastEventId;

  final String origin;

  final List<MessagePort> ports;

  @Creates('Client|ServiceWorker|MessagePort')
  @Returns('Client|ServiceWorker|MessagePort|Null')
  final Object source;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("External")
class External extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory External._() {
    throw new UnsupportedError("Not supported");
  }

  void AddSearchProvider() native;

  void IsSearchProviderInstalled() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FaceDetector")
class FaceDetector extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FaceDetector._() {
    throw new UnsupportedError("Not supported");
  }

  factory FaceDetector([Map faceDetectorOptions]) {
    if (faceDetectorOptions != null) {
      var faceDetectorOptions_1 =
          convertDartToNative_Dictionary(faceDetectorOptions);
      return FaceDetector._create_1(faceDetectorOptions_1);
    }
    return FaceDetector._create_2();
  }
  static FaceDetector _create_1(faceDetectorOptions) =>
      JS('FaceDetector', 'new FaceDetector(#)', faceDetectorOptions);
  static FaceDetector _create_2() => JS('FaceDetector', 'new FaceDetector()');

  Future<List<DetectedFace>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<DetectedFace>>(JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FederatedCredential")
class FederatedCredential extends Credential implements CredentialUserData {
  // To suppress missing implicit constructor warnings.
  factory FederatedCredential._() {
    throw new UnsupportedError("Not supported");
  }

  factory FederatedCredential(Map data) {
    var data_1 = convertDartToNative_Dictionary(data);
    return FederatedCredential._create_1(data_1);
  }
  static FederatedCredential _create_1(data) =>
      JS('FederatedCredential', 'new FederatedCredential(#)', data);

  final String protocol;

  final String provider;

  // From CredentialUserData

  @JSName('iconURL')
  final String iconUrl;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FetchEvent")
class FetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory FetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory FetchEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return FetchEvent._create_1(type, eventInitDict_1);
  }
  static FetchEvent _create_1(type, eventInitDict) =>
      JS('FetchEvent', 'new FetchEvent(#,#)', type, eventInitDict);

  final String clientId;

  final bool isReload;

  Future get preloadResponse =>
      promiseToFuture(JS("", "#.preloadResponse", this));

  final _Request request;

  void respondWith(Future r) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLFieldSetElement")
class FieldSetElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FieldSetElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory FieldSetElement() => JS(
      'returns:FieldSetElement;creates:FieldSetElement;new:true',
      '#.createElement(#)',
      document,
      "fieldset");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FieldSetElement.created() : super.created();

  bool disabled;

  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> elements;

  final FormElement form;

  String name;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("File")
class File extends Blob {
  // To suppress missing implicit constructor warnings.
  factory File._() {
    throw new UnsupportedError("Not supported");
  }

  factory File(List<Object> fileBits, String fileName, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return File._create_1(fileBits, fileName, options_1);
    }
    return File._create_2(fileBits, fileName);
  }
  static File _create_1(fileBits, fileName, options) =>
      JS('File', 'new File(#,#,#)', fileBits, fileName, options);
  static File _create_2(fileBits, fileName) =>
      JS('File', 'new File(#,#)', fileBits, fileName);

  final int lastModified;

  DateTime get lastModifiedDate =>
      convertNativeToDart_DateTime(this._get_lastModifiedDate);
  @JSName('lastModifiedDate')
  @Creates('Null')
  final dynamic _get_lastModifiedDate;

  final String name;

  @JSName('webkitRelativePath')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final String relativePath;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _FileCallback(File file);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileEntry")
class FileEntry extends Entry {
  // To suppress missing implicit constructor warnings.
  factory FileEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createWriter')
  void _createWriter(_FileWriterCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('createWriter')
  Future<FileWriter> createWriter() {
    var completer = new Completer<FileWriter>();
    _createWriter((value) {
      applyExtension('FileWriter', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('file')
  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback])
      native;

  @JSName('file')
  Future<File> file() {
    var completer = new Completer<File>();
    _file((value) {
      applyExtension('File', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileList")
class FileList extends Interceptor
    with ListMixin<File>, ImmutableListMixin<File>
    implements List<File>, JavaScriptIndexingBehavior<File> {
  // To suppress missing implicit constructor warnings.
  factory FileList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  File operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("File", "#[#]", this, index);
  }

  void operator []=(int index, File value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<File> mixins.
  // File is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  File get first {
    if (this.length > 0) {
      return JS('File', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  File get last {
    int len = this.length;
    if (len > 0) {
      return JS('File', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  File get single {
    int len = this.length;
    if (len == 1) {
      return JS('File', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  File elementAt(int index) => this[index];
  // -- end List<File> mixins.

  File item(int index) native;
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileReader")
class FileReader extends EventTarget {
  Object get result {
    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
    if (res is ByteBuffer) {
      return new Uint8List.view(res);
    }
    return res;
  }

  // To suppress missing implicit constructor warnings.
  factory FileReader._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> errorEvent =
      const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEvent =
      const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEndEvent =
      const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadStartEvent =
      const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  factory FileReader() {
    return FileReader._create_1();
  }
  static FileReader _create_1() => JS('FileReader', 'new FileReader()');

  static const int DONE = 2;

  static const int EMPTY = 0;

  static const int LOADING = 1;

  final DomException error;

  final int readyState;

  void abort() native;

  void readAsArrayBuffer(Blob blob) native;

  @JSName('readAsDataURL')
  void readAsDataUrl(Blob blob) native;

  void readAsText(Blob blob, [String label]) native;

  /// Stream of `abort` events handled by this [FileReader].
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileReader].
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [FileReader].
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [FileReader].
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [FileReader].
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileReader].
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("DOMFileSystem")
class FileSystem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FileSystem._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitRequestFileSystem)');

  final String name;

  final DirectoryEntry root;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _FileSystemCallback(FileSystem fileSystem);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileWriter")
class FileWriter extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory FileWriter._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `write` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> writeEvent =
      const EventStreamProvider<ProgressEvent>('write');

  /**
   * Static factory designed to expose `writeend` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> writeEndEvent =
      const EventStreamProvider<ProgressEvent>('writeend');

  /**
   * Static factory designed to expose `writestart` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> writeStartEvent =
      const EventStreamProvider<ProgressEvent>('writestart');

  static const int DONE = 2;

  static const int INIT = 0;

  static const int WRITING = 1;

  final DomException error;

  final int length;

  final int position;

  final int readyState;

  void abort() native;

  void seek(int position) native;

  void truncate(int size) native;

  void write(Blob data) native;

  /// Stream of `abort` events handled by this [FileWriter].
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileWriter].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileWriter].
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `write` events handled by this [FileWriter].
  Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);

  /// Stream of `writeend` events handled by this [FileWriter].
  Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);

  /// Stream of `writestart` events handled by this [FileWriter].
  Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _FileWriterCallback(FileWriter fileWriter);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FocusEvent")
class FocusEvent extends UIEvent {
  // To suppress missing implicit constructor warnings.
  factory FocusEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory FocusEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return FocusEvent._create_1(type, eventInitDict_1);
    }
    return FocusEvent._create_2(type);
  }
  static FocusEvent _create_1(type, eventInitDict) =>
      JS('FocusEvent', 'new FocusEvent(#,#)', type, eventInitDict);
  static FocusEvent _create_2(type) =>
      JS('FocusEvent', 'new FocusEvent(#)', type);

  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @Creates('Null')
  final dynamic _get_relatedTarget;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFace")
class FontFace extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() {
    throw new UnsupportedError("Not supported");
  }

  factory FontFace(String family, Object source, [Map descriptors]) {
    if (descriptors != null) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return FontFace._create_1(family, source, descriptors_1);
    }
    return FontFace._create_2(family, source);
  }
  static FontFace _create_1(family, source, descriptors) =>
      JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);
  static FontFace _create_2(family, source) =>
      JS('FontFace', 'new FontFace(#,#)', family, source);

  String display;

  String family;

  String featureSettings;

  Future<FontFace> get loaded =>
      promiseToFuture<FontFace>(JS("", "#.loaded", this));

  final String status;

  String stretch;

  String style;

  String unicodeRange;

  String variant;

  String weight;

  Future<FontFace> load() =>
      promiseToFuture<FontFace>(JS("", "#.load()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFaceSet")
class FontFaceSet extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSet._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<FontFaceSetLoadEvent> loadingEvent =
      const EventStreamProvider<FontFaceSetLoadEvent>('loading');

  static const EventStreamProvider<FontFaceSetLoadEvent> loadingDoneEvent =
      const EventStreamProvider<FontFaceSetLoadEvent>('loadingdone');

  static const EventStreamProvider<FontFaceSetLoadEvent> loadingErrorEvent =
      const EventStreamProvider<FontFaceSetLoadEvent>('loadingerror');

  final String status;

  FontFaceSet add(FontFace arg) native;

  bool check(String font, [String text]) native;

  void clear() native;

  bool delete(FontFace arg) native;

  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native;

  bool has(FontFace arg) native;

  Stream<FontFaceSetLoadEvent> get onLoading => loadingEvent.forTarget(this);

  Stream<FontFaceSetLoadEvent> get onLoadingDone =>
      loadingDoneEvent.forTarget(this);

  Stream<FontFaceSetLoadEvent> get onLoadingError =>
      loadingErrorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFaceSetLoadEvent")
class FontFaceSetLoadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSetLoadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory FontFaceSetLoadEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return FontFaceSetLoadEvent._create_1(type, eventInitDict_1);
    }
    return FontFaceSetLoadEvent._create_2(type);
  }
  static FontFaceSetLoadEvent _create_1(type, eventInitDict) => JS(
      'FontFaceSetLoadEvent',
      'new FontFaceSetLoadEvent(#,#)',
      type,
      eventInitDict);
  static FontFaceSetLoadEvent _create_2(type) =>
      JS('FontFaceSetLoadEvent', 'new FontFaceSetLoadEvent(#)', type);

  final List<FontFace> fontfaces;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFaceSource")
class FontFaceSource extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSource._() {
    throw new UnsupportedError("Not supported");
  }

  final FontFaceSet fonts;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ForeignFetchEvent")
class ForeignFetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ForeignFetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ForeignFetchEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return ForeignFetchEvent._create_1(type, eventInitDict_1);
  }
  static ForeignFetchEvent _create_1(type, eventInitDict) => JS(
      'ForeignFetchEvent', 'new ForeignFetchEvent(#,#)', type, eventInitDict);

  final String origin;

  final _Request request;

  void respondWith(Future r) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("FormData")
class FormData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FormData._() {
    throw new UnsupportedError("Not supported");
  }

  factory FormData([FormElement form]) {
    if (form != null) {
      return FormData._create_1(form);
    }
    return FormData._create_2();
  }
  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
  static FormData _create_2() => JS('FormData', 'new FormData()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.FormData)');

  void append(String name, String value) native;

  @JSName('append')
  void appendBlob(String name, Blob value, [String filename]) native;

  void delete(String name) native;

  Object get(String name) native;

  List<Object> getAll(String name) native;

  bool has(String name) native;

  void set(String name, value, [String filename]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLFormElement")
class FormElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FormElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory FormElement() => JS(
      'returns:FormElement;creates:FormElement;new:true',
      '#.createElement(#)',
      document,
      "form");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FormElement.created() : super.created();

  String acceptCharset;

  String action;

  String autocomplete;

  String encoding;

  String enctype;

  final int length;

  String method;

  String name;

  bool noValidate;

  String target;

  Object __getter__(String name) native;

  bool checkValidity() native;

  Element item(int index) native;

  bool reportValidity() native;

  void requestAutocomplete(Map details) {
    var details_1 = convertDartToNative_Dictionary(details);
    _requestAutocomplete_1(details_1);
    return;
  }

  @JSName('requestAutocomplete')
  void _requestAutocomplete_1(details) native;

  void reset() native;

  void submit() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void FrameRequestCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void FunctionStringCallback(String data);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Gamepad")
class Gamepad extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() {
    throw new UnsupportedError("Not supported");
  }

  final List<num> axes;

  @Creates('JSExtendableArray|GamepadButton')
  @Returns('JSExtendableArray')
  final List<GamepadButton> buttons;

  final bool connected;

  final int displayId;

  final String hand;

  final String id;

  final int index;

  final String mapping;

  final GamepadPose pose;

  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadButton")
class GamepadButton extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GamepadButton._() {
    throw new UnsupportedError("Not supported");
  }

  final bool pressed;

  final bool touched;

  final num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadEvent")
class GamepadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory GamepadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory GamepadEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return GamepadEvent._create_1(type, eventInitDict_1);
    }
    return GamepadEvent._create_2(type);
  }
  static GamepadEvent _create_1(type, eventInitDict) =>
      JS('GamepadEvent', 'new GamepadEvent(#,#)', type, eventInitDict);
  static GamepadEvent _create_2(type) =>
      JS('GamepadEvent', 'new GamepadEvent(#)', type);

  final Gamepad gamepad;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadPose")
class GamepadPose extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GamepadPose._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List angularAcceleration;

  final Float32List angularVelocity;

  final bool hasOrientation;

  final bool hasPosition;

  final Float32List linearAcceleration;

  final Float32List linearVelocity;

  final Float32List orientation;

  final Float32List position;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("Geolocation")
class Geolocation extends Interceptor {
  Future<Geoposition> getCurrentPosition(
      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition((position) {
        completer.complete(_ensurePosition(position));
      }, (error) {
        completer.completeError(error);
      }, options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  Stream<Geoposition> watchPosition(
      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    // TODO(jacobr): it seems like a bug that we have to specifiy the static
    // type here for controller.stream to have the right type.
    // dartbug.com/26278
    StreamController<Geoposition> controller;
    controller = new StreamController<Geoposition>(
        sync: true,
        onListen: () {
          assert(watchId == null);
          watchId = _watchPosition((position) {
            controller.add(_ensurePosition(position));
          }, (error) {
            controller.addError(error);
          }, options);
        },
        onCancel: () {
          assert(watchId != null);
          _clearWatch(watchId);
        });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    try {
      // Firefox may throw on this.
      if (domPosition is Geoposition) {
        return domPosition;
      }
    } catch (e) {}
    return new _GeopositionWrapper(domPosition);
  }

  // To suppress missing implicit constructor warnings.
  factory Geolocation._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('clearWatch')
  void _clearWatch(int watchID) native;

  void _getCurrentPosition(_PositionCallback successCallback,
      [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      var options_2 = convertDartToNative_Dictionary(options);
      _getCurrentPosition_1(successCallback_1, errorCallback, options_2);
      return;
    }
    if (errorCallback != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      _getCurrentPosition_2(successCallback_1, errorCallback);
      return;
    }
    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
    _getCurrentPosition_3(successCallback_1);
    return;
  }

  @JSName('getCurrentPosition')
  void _getCurrentPosition_1(
      successCallback, _PositionErrorCallback errorCallback, options) native;
  @JSName('getCurrentPosition')
  void _getCurrentPosition_2(
      successCallback, _PositionErrorCallback errorCallback) native;
  @JSName('getCurrentPosition')
  void _getCurrentPosition_3(successCallback) native;

  int _watchPosition(_PositionCallback successCallback,
      [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      var options_2 = convertDartToNative_Dictionary(options);
      return _watchPosition_1(successCallback_1, errorCallback, options_2);
    }
    if (errorCallback != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      return _watchPosition_2(successCallback_1, errorCallback);
    }
    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
    return _watchPosition_3(successCallback_1);
  }

  @JSName('watchPosition')
  int _watchPosition_1(
      successCallback, _PositionErrorCallback errorCallback, options) native;
  @JSName('watchPosition')
  int _watchPosition_2(successCallback, _PositionErrorCallback errorCallback)
      native;
  @JSName('watchPosition')
  int _watchPosition_3(successCallback) native;
}

/**
 * Wrapper for Firefox- it returns an object which we cannot map correctly.
 * Basically Firefox was returning a [xpconnect wrapped nsIDOMGeoPosition] but
 * which has further oddities.
 */
class _GeopositionWrapper implements Geoposition {
  var _ptr;
  _GeopositionWrapper(this._ptr);

  Coordinates get coords => JS('Coordinates', '#.coords', _ptr);
  int get timestamp => JS('int', '#.timestamp', _ptr);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Position")
class Geoposition extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() {
    throw new UnsupportedError("Not supported");
  }

  final Coordinates coords;

  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// We implement EventTarget and have stubs for its methods because it's tricky to
// convince the scripts to make our instance methods abstract, and the bodies that
// get generated require `this` to be an EventTarget.
abstract class GlobalEventHandlers implements EventTarget {
  void addEventListener(String type, dynamic listener(Event event),
      [bool useCapture]);
  bool dispatchEvent(Event event);
  void removeEventListener(String type, dynamic listener(Event event),
      [bool useCapture]);
  Events get on;

  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  static const EventStreamProvider<Event> canPlayEvent =
      const EventStreamProvider<Event>('canplay');

  static const EventStreamProvider<Event> canPlayThroughEvent =
      const EventStreamProvider<Event>('canplaythrough');

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  static const EventStreamProvider<MouseEvent> clickEvent =
      const EventStreamProvider<MouseEvent>('click');

  static const EventStreamProvider<MouseEvent> contextMenuEvent =
      const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  static const EventStreamProvider<Event> doubleClickEvent =
      const EventStreamProvider<Event>('dblclick');

  static const EventStreamProvider<MouseEvent> dragEvent =
      const EventStreamProvider<MouseEvent>('drag');

  static const EventStreamProvider<MouseEvent> dragEndEvent =
      const EventStreamProvider<MouseEvent>('dragend');

  static const EventStreamProvider<MouseEvent> dragEnterEvent =
      const EventStreamProvider<MouseEvent>('dragenter');

  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
      const EventStreamProvider<MouseEvent>('dragleave');

  static const EventStreamProvider<MouseEvent> dragOverEvent =
      const EventStreamProvider<MouseEvent>('dragover');

  static const EventStreamProvider<MouseEvent> dragStartEvent =
      const EventStreamProvider<MouseEvent>('dragstart');

  static const EventStreamProvider<MouseEvent> dropEvent =
      const EventStreamProvider<MouseEvent>('drop');

  static const EventStreamProvider<Event> durationChangeEvent =
      const EventStreamProvider<Event>('durationchange');

  static const EventStreamProvider<Event> emptiedEvent =
      const EventStreamProvider<Event>('emptied');

  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  static const EventStreamProvider<Event> inputEvent =
      const EventStreamProvider<Event>('input');

  static const EventStreamProvider<Event> invalidEvent =
      const EventStreamProvider<Event>('invalid');

  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
      const EventStreamProvider<KeyboardEvent>('keydown');

  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
      const EventStreamProvider<KeyboardEvent>('keypress');

  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
      const EventStreamProvider<KeyboardEvent>('keyup');

  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  static const EventStreamProvider<Event> loadedDataEvent =
      const EventStreamProvider<Event>('loadeddata');

  static const EventStreamProvider<Event> loadedMetadataEvent =
      const EventStreamProvider<Event>('loadedmetadata');

  static const EventStreamProvider<MouseEvent> mouseDownEvent =
      const EventStreamProvider<MouseEvent>('mousedown');

  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
      const EventStreamProvider<MouseEvent>('mouseenter');

  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
      const EventStreamProvider<MouseEvent>('mouseleave');

  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
      const EventStreamProvider<MouseEvent>('mousemove');

  static const EventStreamProvider<MouseEvent> mouseOutEvent =
      const EventStreamProvider<MouseEvent>('mouseout');

  static const EventStreamProvider<MouseEvent> mouseOverEvent =
      const EventStreamProvider<MouseEvent>('mouseover');

  static const EventStreamProvider<MouseEvent> mouseUpEvent =
      const EventStreamProvider<MouseEvent>('mouseup');

  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const EventStreamProvider<WheelEvent>('mousewheel');

  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  static const EventStreamProvider<Event> playEvent =
      const EventStreamProvider<Event>('play');

  static const EventStreamProvider<Event> playingEvent =
      const EventStreamProvider<Event>('playing');

  static const EventStreamProvider<Event> rateChangeEvent =
      const EventStreamProvider<Event>('ratechange');

  static const EventStreamProvider<Event> resetEvent =
      const EventStreamProvider<Event>('reset');

  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  static const EventStreamProvider<Event> seekedEvent =
      const EventStreamProvider<Event>('seeked');

  static const EventStreamProvider<Event> seekingEvent =
      const EventStreamProvider<Event>('seeking');

  static const EventStreamProvider<Event> selectEvent =
      const EventStreamProvider<Event>('select');

  static const EventStreamProvider<Event> stalledEvent =
      const EventStreamProvider<Event>('stalled');

  static const EventStreamProvider<Event> submitEvent =
      const EventStreamProvider<Event>('submit');

  static const EventStreamProvider<Event> suspendEvent =
      const EventStreamProvider<Event>('suspend');

  static const EventStreamProvider<Event> timeUpdateEvent =
      const EventStreamProvider<Event>('timeupdate');

  static const EventStreamProvider<TouchEvent> touchCancelEvent =
      const EventStreamProvider<TouchEvent>('touchcancel');

  static const EventStreamProvider<TouchEvent> touchEndEvent =
      const EventStreamProvider<TouchEvent>('touchend');

  static const EventStreamProvider<TouchEvent> touchMoveEvent =
      const EventStreamProvider<TouchEvent>('touchmove');

  static const EventStreamProvider<TouchEvent> touchStartEvent =
      const EventStreamProvider<TouchEvent>('touchstart');

  static const EventStreamProvider<Event> volumeChangeEvent =
      const EventStreamProvider<Event>('volumechange');

  static const EventStreamProvider<Event> waitingEvent =
      const EventStreamProvider<Event>('waiting');

  static const EventStreamProvider<WheelEvent> wheelEvent =
      const EventStreamProvider<WheelEvent>('wheel');

  Stream<Event> get onAbort => abortEvent.forTarget(this);

  Stream<Event> get onBlur => blurEvent.forTarget(this);

  Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);

  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);

  Stream<Event> get onChange => changeEvent.forTarget(this);

  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondblclick')
  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

  Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);

  Stream<Event> get onEmptied => emptiedEvent.forTarget(this);

  Stream<Event> get onEnded => endedEvent.forTarget(this);

  Stream<Event> get onError => errorEvent.forTarget(this);

  Stream<Event> get onFocus => focusEvent.forTarget(this);

  Stream<Event> get onInput => inputEvent.forTarget(this);

  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  Stream<Event> get onLoad => loadEvent.forTarget(this);

  Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);

  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);

  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

  Stream<Event> get onPause => pauseEvent.forTarget(this);

  Stream<Event> get onPlay => playEvent.forTarget(this);

  Stream<Event> get onPlaying => playingEvent.forTarget(this);

  Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);

  Stream<Event> get onReset => resetEvent.forTarget(this);

  Stream<Event> get onResize => resizeEvent.forTarget(this);

  Stream<Event> get onScroll => scrollEvent.forTarget(this);

  Stream<Event> get onSeeked => seekedEvent.forTarget(this);

  Stream<Event> get onSeeking => seekingEvent.forTarget(this);

  Stream<Event> get onSelect => selectEvent.forTarget(this);

  Stream<Event> get onStalled => stalledEvent.forTarget(this);

  Stream<Event> get onSubmit => submitEvent.forTarget(this);

  Stream<Event> get onSuspend => suspendEvent.forTarget(this);

  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);

  Stream<TouchEvent> get onTouchCancel => touchCancelEvent.forTarget(this);

  Stream<TouchEvent> get onTouchEnd => touchEndEvent.forTarget(this);

  Stream<TouchEvent> get onTouchMove => touchMoveEvent.forTarget(this);

  Stream<TouchEvent> get onTouchStart => touchStartEvent.forTarget(this);

  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);

  Stream<Event> get onWaiting => waitingEvent.forTarget(this);

  Stream<WheelEvent> get onWheel => wheelEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Gyroscope")
class Gyroscope extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory Gyroscope._() {
    throw new UnsupportedError("Not supported");
  }

  factory Gyroscope([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return Gyroscope._create_1(sensorOptions_1);
    }
    return Gyroscope._create_2();
  }
  static Gyroscope _create_1(sensorOptions) =>
      JS('Gyroscope', 'new Gyroscope(#)', sensorOptions);
  static Gyroscope _create_2() => JS('Gyroscope', 'new Gyroscope()');

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An `<hr>` tag.
 */
@Native("HTMLHRElement")
class HRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HRElement() => JS('returns:HRElement;creates:HRElement;new:true',
      '#.createElement(#)', document, "hr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HRElement.created() : super.created();

  String color;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HashChangeEvent")
class HashChangeEvent extends Event {
  factory HashChangeEvent(String type,
      {bool canBubble: true,
      bool cancelable: true,
      String oldUrl,
      String newUrl}) {
    var options = {
      'canBubble': canBubble,
      'cancelable': cancelable,
      'oldURL': oldUrl,
      'newURL': newUrl,
    };
    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)', type,
        convertDartToNative_Dictionary(options));
  }

  factory HashChangeEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return HashChangeEvent._create_1(type, eventInitDict_1);
    }
    return HashChangeEvent._create_2(type);
  }
  static HashChangeEvent _create_1(type, eventInitDict) =>
      JS('HashChangeEvent', 'new HashChangeEvent(#,#)', type, eventInitDict);
  static HashChangeEvent _create_2(type) =>
      JS('HashChangeEvent', 'new HashChangeEvent(#)', type);

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('HashChangeEvent');

  @JSName('newURL')
  final String newUrl;

  @JSName('oldURL')
  final String oldUrl;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHeadElement")
class HeadElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HeadElement() => JS(
      'returns:HeadElement;creates:HeadElement;new:true',
      '#.createElement(#)',
      document,
      "head");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Headers")
class Headers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Headers._() {
    throw new UnsupportedError("Not supported");
  }

  factory Headers([Object init]) {
    if (init != null) {
      return Headers._create_1(init);
    }
    return Headers._create_2();
  }
  static Headers _create_1(init) => JS('Headers', 'new Headers(#)', init);
  static Headers _create_2() => JS('Headers', 'new Headers()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHeadingElement")
class HeadingElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadingElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HeadingElement.h1() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h1");

  factory HeadingElement.h2() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h2");

  factory HeadingElement.h3() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h3");

  factory HeadingElement.h4() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h4");

  factory HeadingElement.h5() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h5");

  factory HeadingElement.h6() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h6");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadingElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("History")
class History extends Interceptor implements HistoryBase {
  /**
   * Checks if the State APIs are supported on the current platform.
   *
   * See also:
   *
   * * [pushState]
   * * [replaceState]
   * * [state]
   */
  static bool get supportsState => JS('bool', '!!window.history.pushState');
  // To suppress missing implicit constructor warnings.
  factory History._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  String scrollRestoration;

  dynamic get state =>
      convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;

  void back() native;

  void forward() native;

  void go([int delta]) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(/*SerializedScriptValue*/ data, String title, String url) {
    var data_1 = convertDartToNative_SerializedScriptValue(data);
    _pushState_1(data_1, title, url);
    return;
  }

  @JSName('pushState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _pushState_1(data, title, url) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(/*SerializedScriptValue*/ data, String title, String url) {
    var data_1 = convertDartToNative_SerializedScriptValue(data);
    _replaceState_1(data_1, title, url);
    return;
  }

  @JSName('replaceState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _replaceState_1(data, title, url) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLCollection")
class HtmlCollection extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  Node item(int index) native;

  Object namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("HTMLDocument")
class HtmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory HtmlDocument._() {
    throw new UnsupportedError("Not supported");
  }

  BodyElement body;

  /// UNSTABLE: Chrome-only - create a Range from the given point.
  @Unstable()
  Range caretRangeFromPoint(int x, int y) {
    return _caretRangeFromPoint(x, y);
  }

  Element elementFromPoint(int x, int y) {
    return _elementFromPoint(x, y);
  }

  HeadElement get head => _head;

  String get lastModified => _lastModified;

  String get preferredStylesheetSet => _preferredStylesheetSet;

  String get referrer => _referrer;

  String get selectedStylesheetSet => _selectedStylesheetSet;
  set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

  List<StyleSheet> get styleSheets => _styleSheets;

  String get title => _title;

  set title(String value) {
    _title = value;
  }

  /**
   * Returns page to standard layout.
   *
   * Has no effect if the page is not in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Fullscreen
   *   API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)
   *   from MDN.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void exitFullscreen() {
    _webkitExitFullscreen();
  }

  /**
   * Register a custom subclass of Element to be instantiatable by the DOM.
   *
   * This is necessary to allow the construction of any custom elements.
   *
   * The class being registered must either subclass HtmlElement or SvgElement.
   * If they subclass these directly then they can be used as:
   *
   *     class FooElement extends HtmlElement{
   *        void created() {
   *          print('FooElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-foo', FooElement);
   *       var myFoo = new Element.tag('x-foo');
   *       // prints 'FooElement created!' to the console.
   *     }
   *
   * The custom element can also be instantiated via HTML using the syntax
   * `<x-foo></x-foo>`
   *
   * Other elements can be subclassed as well:
   *
   *     class BarElement extends InputElement{
   *        void created() {
   *          print('BarElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-bar', BarElement);
   *       var myBar = new Element.tag('input', 'x-bar');
   *       // prints 'BarElement created!' to the console.
   *     }
   *
   * This custom element can also be instantiated via HTML using the syntax
   * `<input is="x-bar"></input>`
   *
   */
  Function registerElement2(String tag, [Map options]) {
    return _registerCustomElement(JS('', 'window'), this, tag, options);
  }

  /** *Deprecated*: use [registerElement] instead. */
  @deprecated
  void register(String tag, Type customElementClass, {String extendsTag}) {
    return registerElement(tag, customElementClass, extendsTag: extendsTag);
  }

  /**
   * Static factory designed to expose `visibilitychange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  static const EventStreamProvider<Event> visibilityChangeEvent =
      const _CustomEventStreamProvider<Event>(
          _determineVisibilityChangeEventType);

  static String _determineVisibilityChangeEventType(EventTarget e) {
    if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
      // Opera 12.10 and Firefox 18 and later support
      return 'visibilitychange';
    } else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
      return 'mozvisibilitychange';
    } else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
      return 'msvisibilitychange';
    } else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
      return 'webkitvisibilitychange';
    }
    return 'visibilitychange';
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  Stream<Event> get onVisibilityChange => visibilityChangeEvent.forTarget(this);

  /// Creates an element upgrader which can be used to change the Dart wrapper
  /// type for elements.
  ///
  /// The type specified must be a subclass of HtmlElement, when an element is
  /// upgraded then the created constructor will be invoked on that element.
  ///
  /// If the type is not a direct subclass of HtmlElement then the extendsTag
  /// parameter must be provided.
  ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
    return new _JSElementUpgrader(this, type, extendsTag);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLFormControlsCollection")
class HtmlFormControlsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() {
    throw new UnsupportedError("Not supported");
  }

  Node item(int index) native;

  Object namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHtmlElement")
class HtmlHtmlElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HtmlHtmlElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HtmlHtmlElement() => JS(
      'returns:HtmlHtmlElement;creates:HtmlHtmlElement;new:true',
      '#.createElement(#)',
      document,
      "html");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlHtmlElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHyperlinkElementUtils")
class HtmlHyperlinkElementUtils extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory HtmlHyperlinkElementUtils._() {
    throw new UnsupportedError("Not supported");
  }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOptionsCollection")
class HtmlOptionsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlOptionsCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('item')
  Element _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
@Native("XMLHttpRequest")
class HttpRequest extends HttpRequestEventTarget {
  /**
   * Creates a GET request for the specified [url].
   *
   * This is similar to [request] but specialized for HTTP GET requests which
   * return text content.
   *
   * To add query parameters, append them to the [url] following a `?`,
   * joining each key to its value with `=` and separating key-value pairs with
   * `&`.
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.getString('users.json?name=$name&id=$id')
   *       .then((String resp) {
   *         // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<String> getString(String url,
      {bool withCredentials, void onProgress(ProgressEvent e)}) {
    return request(url,
            withCredentials: withCredentials, onProgress: onProgress)
        .then((HttpRequest xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of [getString]. This method is similar
   * to sending a [FormData] object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials,
      String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {
    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url,
        method: 'POST',
        withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders,
        sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method,
      bool withCredentials,
      String responseType,
      String mimeType,
      Map<String, String> requestHeaders,
      sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      var accepted = xhr.status >= 200 && xhr.status < 300;
      var fileUri = xhr.status == 0; // file:// URIs have status of 0.
      var notModified = xhr.status == 304;
      // Redirect status is specified up to 307, but others have been used in
      // practice. Notably Google Drive uses 308 Resume Incomplete for
      // resumable uploads, and it's also been used as a redirect. The
      // redirect case will be handled by the browser before it gets to us,
      // so if we see it we should pass it through to the user.
      var unknownRedirect = xhr.status > 307 && xhr.status < 400;

      if (accepted || fileUri || notModified || unknownRedirect) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onprogress" in #)', xhr);
  }

  /**
   * Checks to see if the current platform supports making cross origin
   * requests.
   *
   * Note that even if cross origin requests are supported, they still may fail
   * if the destination server does not support CORS requests.
   */
  static bool get supportsCrossOrigin {
    var xhr = new HttpRequest();
    return JS('bool', '("withCredentials" in #)', xhr);
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onloadend" in #)', xhr);
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
    var xhr = new HttpRequest();
    return JS('bool', '("overrideMimeType" in #)', xhr);
  }

  /**
   * Makes a cross-origin request to the specified URL.
   *
   * This API provides a subset of [request] which works on IE9. If IE9
   * cross-origin support is not required then [request] should be used instead.
   */
  static Future<String> requestCrossOrigin(String url,
      {String method, String sendData}) {
    if (supportsCrossOrigin) {
      return request(url, method: method, sendData: sendData).then((xhr) {
        return xhr.responseText;
      });
    }
    var completer = new Completer<String>();
    if (method == null) {
      method = 'GET';
    }
    var xhr = JS('var', 'new XDomainRequest()');
    JS('', '#.open(#, #)', xhr, method, url);
    JS(
        '',
        '#.onload = #',
        xhr,
        convertDartClosureToJS((e) {
          var response = JS('String', '#.responseText', xhr);
          completer.complete(response);
        }, 1));
    JS(
        '',
        '#.onerror = #',
        xhr,
        convertDartClosureToJS((e) {
          completer.completeError(e);
        }, 1));

    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
    // not specified
    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
    JS('', '#.onprogress = {}', xhr);
    JS('', '#.ontimeout = {}', xhr);
    JS('', '#.timeout = Number.MAX_VALUE', xhr);

    if (sendData != null) {
      JS('', '#.send(#)', xhr, sendData);
    } else {
      JS('', '#.send()', xhr);
    }

    return completer.future;
  }

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

  /**
   * Specify the desired `url`, and `method` to use in making the request.
   *
   * By default the request is done asyncronously, with no user or password
   * authentication information. If `async` is false, the request will be sent
   * synchronously.
   *
   * Calling `open` again on a currently active request is equivalent to
   * calling [abort].
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `open` method is intended only for more complex HTTP requests where
   * finer-grained control is needed.
   */
  void open(String method, String url,
      {bool async, String user, String password}) native;

  // To suppress missing implicit constructor warnings.
  factory HttpRequest._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [HttpRequest].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> readyStateChangeEvent =
      const EventStreamProvider<Event>('readystatechange');

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  factory HttpRequest() {
    return HttpRequest._create_1();
  }
  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');

  static const int DONE = 4;

  static const int HEADERS_RECEIVED = 2;

  static const int LOADING = 3;

  static const int OPENED = 1;

  static const int UNSENT = 0;

  /**
   * Indicator of the current state of the request:
   *
   * <table>
   *   <tr>
   *     <td>Value</td>
   *     <td>State</td>
   *     <td>Meaning</td>
   *   </tr>
   *   <tr>
   *     <td>0</td>
   *     <td>unsent</td>
   *     <td><code>open()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>1</td>
   *     <td>opened</td>
   *     <td><code>send()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>2</td>
   *     <td>headers received</td>
   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
   *   </tr>
   *   <tr>
   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
   *   </tr>
   *   <tr>
   *     <td>4</td> <td>done</td> <td>request is complete</td>
   *   </tr>
   * </table>
   */
  final int readyState;

  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
  @JSName('response')
  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates(
      'NativeByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
  final dynamic _get_response;

  /**
   * The response in String form or empty String on failure.
   */
  final String responseText;

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN
   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
   */
  String responseType;

  @JSName('responseURL')
  final String responseUrl;

  @JSName('responseXML')
  /**
   * The request response, or null on failure.
   *
   * The response is processed as
   * `text/xml` stream, unless responseType = 'document' and the request is
   * synchronous.
   */
  final Document responseXml;

  /**
   * The HTTP result code from the request (200, 404, etc).
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  final int status;

  /**
   * The request response string (such as \"200 OK\").
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  final String statusText;

  /**
   * Length of time in milliseconds before a request is automatically
   * terminated.
   *
   * When the time has passed, a [TimeoutEvent] is dispatched.
   *
   * If [timeout] is set to 0, then the request will not time out.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
   *   from MDN.
   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   *   from W3C.
   */
  int timeout;

  /**
   * [EventTarget] that can hold listeners to track the progress of the request.
   * The events fired will be members of [HttpRequestUploadEvents].
   */
  @Unstable()
  final HttpRequestUpload upload;

  /**
   * True if cross-site requests should use credentials such as cookies
   * or authorization headers; false otherwise.
   *
   * This value is ignored for same-site requests.
   */
  bool withCredentials;

  /**
   * Stop the current request.
   *
   * The request can only be stopped if readyState is `HEADERS_RECEIVED` or
   * `LOADING`. If this method is not in the process of being sent, the method
   * has no effect.
   */
  void abort() native;

  /**
   * Retrieve all the response headers from a request.
   *
   * `null` if no headers have been received. For multipart requests,
   * `getAllResponseHeaders` will return the response headers for the current
   * part of the request.
   *
   * See also [HTTP response
   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @Unstable()
  String getAllResponseHeaders() native;

  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response
   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @Unstable()
  String getResponseHeader(String name) native;

  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml).
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String mime) native;

  /**
   * Send the request with any given `data`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `send` method is intended only for more complex HTTP requests where
   * finer-grained control is needed.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   *   from MDN.
   */
  void send([body_OR_data]) native;

  /**
   * Sets the value of an HTTP request header.
   *
   * This method should be called after the request is opened, but before
   * the request is sent.
   *
   * Multiple calls with the same header will combine all their values into a
   * single header.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
   *   from MDN.
   * * [The setRequestHeader()
   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
   *   from W3C.
   */
  void setRequestHeader(String name, String value) native;

  /// Stream of `readystatechange` events handled by this [HttpRequest].
/**
   * Event listeners to be notified every time the [HttpRequest]
   * object's `readyState` changes values.
   */
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("XMLHttpRequestEventTarget")
class HttpRequestEventTarget extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestEventTarget._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> errorEvent =
      const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEvent =
      const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEndEvent =
      const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadStartEvent =
      const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `timeout` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> timeoutEvent =
      const EventStreamProvider<ProgressEvent>('timeout');

  /// Stream of `abort` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [HttpRequestEventTarget].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [HttpRequestEventTarget].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `timeout` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("XMLHttpRequestUpload")
class HttpRequestUpload extends HttpRequestEventTarget {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestUpload._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLIFrameElement")
class IFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory IFrameElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory IFrameElement() => JS(
      'returns:IFrameElement;creates:IFrameElement;new:true',
      '#.createElement(#)',
      document,
      "iframe");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  IFrameElement.created() : super.created();

  String allow;

  bool allowFullscreen;

  bool allowPaymentRequest;

  WindowBase get contentWindow =>
      _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  String csp;

  String height;

  String name;

  String referrerPolicy;

  final DomTokenList sandbox;

  String src;

  String srcdoc;

  String width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("IdleDeadline")
class IdleDeadline extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IdleDeadline._() {
    throw new UnsupportedError("Not supported");
  }

  final bool didTimeout;

  double timeRemaining() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void IdleRequestCallback(IdleDeadline deadline);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageBitmap")
class ImageBitmap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() {
    throw new UnsupportedError("Not supported");
  }

  final int height;

  final int width;

  void close() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageBitmapRenderingContext")
class ImageBitmapRenderingContext extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmapRenderingContext._() {
    throw new UnsupportedError("Not supported");
  }

  final CanvasElement canvas;

  void transferFromImageBitmap(ImageBitmap bitmap) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageCapture")
class ImageCapture extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageCapture._() {
    throw new UnsupportedError("Not supported");
  }

  factory ImageCapture(MediaStreamTrack track) {
    return ImageCapture._create_1(track);
  }
  static ImageCapture _create_1(track) =>
      JS('ImageCapture', 'new ImageCapture(#)', track);

  final MediaStreamTrack track;

  Future<PhotoCapabilities> getPhotoCapabilities() =>
      promiseToFuture<PhotoCapabilities>(
          JS("", "#.getPhotoCapabilities()", this));

  Future<Map<String, dynamic>> getPhotoSettings() =>
      promiseToFutureAsMap(JS("", "#.getPhotoSettings()", this));

  Future<ImageBitmap> grabFrame() =>
      promiseToFuture<ImageBitmap>(JS("", "#.grabFrame()", this));

  Future setOptions(Map photoSettings) {
    var photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
    return promiseToFuture(JS("", "#.setOptions(#)", this, photoSettings_dict));
  }

  Future<Blob> takePhoto([Map photoSettings]) {
    var photoSettings_dict = null;
    if (photoSettings != null) {
      photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
    }
    return promiseToFuture<Blob>(
        JS("", "#.takePhoto(#)", this, photoSettings_dict));
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageData")
class ImageData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageData._() {
    throw new UnsupportedError("Not supported");
  }

  factory ImageData(data_OR_sw, int sh_OR_sw, [int sh]) {
    if ((sh_OR_sw is int) && (data_OR_sw is int) && sh == null) {
      return ImageData._create_1(data_OR_sw, sh_OR_sw);
    }
    if ((sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList) && sh == null) {
      return ImageData._create_2(data_OR_sw, sh_OR_sw);
    }
    if ((sh is int) && (sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList)) {
      return ImageData._create_3(data_OR_sw, sh_OR_sw, sh);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static ImageData _create_1(data_OR_sw, sh_OR_sw) =>
      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
  static ImageData _create_2(data_OR_sw, sh_OR_sw) =>
      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
  static ImageData _create_3(data_OR_sw, sh_OR_sw, sh) =>
      JS('ImageData', 'new ImageData(#,#,#)', data_OR_sw, sh_OR_sw, sh);

  @Creates('NativeUint8ClampedList')
  @Returns('NativeUint8ClampedList')
  final Uint8ClampedList data;

  final int height;

  final int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLImageElement")
class ImageElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory ImageElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ImageElement({String src, int width, int height}) {
    ImageElement e = JS('returns:ImageElement;creates:ImageElement;new:true',
        '#.createElement(#)', document, "img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ImageElement.created() : super.created();

  String alt;

  String async;

  final bool complete;

  String crossOrigin;

  final String currentSrc;

  int height;

  bool isMap;

  final int naturalHeight;

  final int naturalWidth;

  String referrerPolicy;

  String sizes;

  String src;

  String srcset;

  String useMap;

  int width;

  Future decode() => promiseToFuture(JS("", "#.decode()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("InputDeviceCapabilities")
class InputDeviceCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory InputDeviceCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  factory InputDeviceCapabilities([Map deviceInitDict]) {
    if (deviceInitDict != null) {
      var deviceInitDict_1 = convertDartToNative_Dictionary(deviceInitDict);
      return InputDeviceCapabilities._create_1(deviceInitDict_1);
    }
    return InputDeviceCapabilities._create_2();
  }
  static InputDeviceCapabilities _create_1(deviceInitDict) => JS(
      'InputDeviceCapabilities',
      'new InputDeviceCapabilities(#)',
      deviceInitDict);
  static InputDeviceCapabilities _create_2() =>
      JS('InputDeviceCapabilities', 'new InputDeviceCapabilities()');

  final bool firesTouchEvents;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLInputElement")
class InputElement extends HtmlElement
    implements
        HiddenInputElement,
        SearchInputElement,
        TextInputElement,
        UrlInputElement,
        TelephoneInputElement,
        EmailInputElement,
        PasswordInputElement,
        DateInputElement,
        MonthInputElement,
        WeekInputElement,
        TimeInputElement,
        LocalDateTimeInputElement,
        NumberInputElement,
        RangeInputElement,
        CheckboxInputElement,
        RadioButtonInputElement,
        FileUploadInputElement,
        SubmitButtonInputElement,
        ImageButtonInputElement,
        ResetButtonInputElement,
        ButtonInputElement {
  factory InputElement({String type}) {
    InputElement e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch (_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  InputElement.created() : super.created();

  String accept;

  String alt;

  String autocapitalize;

  String autocomplete;

  bool autofocus;

  String capture;

  bool checked;

  bool defaultChecked;

  String defaultValue;

  String dirName;

  bool disabled;

  @Returns('FileList|Null')
  @Creates('FileList')
  List<File> files;

  final FormElement form;

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;

  int height;

  bool incremental;

  bool indeterminate;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  final HtmlElement list;

  String max;

  int maxLength;

  String min;

  int minLength;

  bool multiple;

  String name;

  String pattern;

  String placeholder;

  bool readOnly;

  bool required;

  String selectionDirection;

  int selectionEnd;

  int selectionStart;

  int size;

  String src;

  String step;

  String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  DateTime get valueAsDate =>
      convertNativeToDart_DateTime(this._get_valueAsDate);
  @JSName('valueAsDate')
  @Creates('Null')
  final dynamic _get_valueAsDate;

  set valueAsDate(DateTime value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value);
  }

  set _set_valueAsDate(/*dynamic*/ value) {
    JS("void", "#.valueAsDate = #", this, value);
  }

  num valueAsNumber;

  @JSName('webkitEntries')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final List<Entry> entries;

  @JSName('webkitdirectory')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  bool directory;

  int width;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void select() native;

  void setCustomValidity(String error) native;

  void setRangeText(String replacement,
      {int start, int end, String selectionMode}) native;

  void setSelectionRange(int start, int end, [String direction]) native;

  void stepDown([int n]) native;

  void stepUp([int n]) native;
}

// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.

/**
 * Exposes the functionality common between all InputElement types.
 */
abstract class InputElementBase implements Element {
  bool autofocus;

  bool disabled;

  bool incremental;

  bool indeterminate;

  List<Node> get labels;

  String name;

  String get validationMessage;

  ValidityState get validity;

  String value;

  bool get willValidate;

  bool checkValidity();

  void setCustomValidity(String error);
}

/**
 * Hidden input which is not intended to be seen or edited by the user.
 */
abstract class HiddenInputElement implements InputElementBase {
  factory HiddenInputElement() => new InputElement(type: 'hidden');
}

/**
 * Base interface for all inputs which involve text editing.
 */
abstract class TextInputElementBase implements InputElementBase {
  String autocomplete;

  int maxLength;

  String pattern;

  String placeholder;

  bool readOnly;

  bool required;

  int size;

  void select();

  String selectionDirection;

  int selectionEnd;

  int selectionStart;

  void setSelectionRange(int start, int end, [String direction]);
}

/**
 * Similar to [TextInputElement], but on platforms where search is styled
 * differently this will get the search style.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class SearchInputElement implements TextInputElementBase {
  factory SearchInputElement() => new InputElement(type: 'search');

  String dirName;

  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'search')).type == 'search';
  }
}

/**
 * A basic text input editor control.
 */
abstract class TextInputElement implements TextInputElementBase {
  factory TextInputElement() => new InputElement(type: 'text');

  String dirName;

  Element get list;
}

/**
 * A control for editing an absolute URL.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class UrlInputElement implements TextInputElementBase {
  factory UrlInputElement() => new InputElement(type: 'url');

  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'url')).type == 'url';
  }
}

/**
 * Represents a control for editing a telephone number.
 *
 * This provides a single line of text with minimal formatting help since
 * there is a wide variety of telephone numbers.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class TelephoneInputElement implements TextInputElementBase {
  factory TelephoneInputElement() => new InputElement(type: 'tel');

  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'tel')).type == 'tel';
  }
}

/**
 * An e-mail address or list of e-mail addresses.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class EmailInputElement implements TextInputElementBase {
  factory EmailInputElement() => new InputElement(type: 'email');

  String autocomplete;

  bool autofocus;

  Element get list;

  int maxLength;

  bool multiple;

  String pattern;

  String placeholder;

  bool readOnly;

  bool required;

  int size;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'email')).type == 'email';
  }
}

/**
 * Text with no line breaks (sensitive information).
 */
abstract class PasswordInputElement implements TextInputElementBase {
  factory PasswordInputElement() => new InputElement(type: 'password');
}

/**
 * Base interface for all input element types which involve ranges.
 */
abstract class RangeInputElementBase implements InputElementBase {
  Element get list;

  String max;

  String min;

  String step;

  num valueAsNumber;

  void stepDown([int n]);

  void stepUp([int n]);
}

/**
 * A date (year, month, day) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class DateInputElement implements RangeInputElementBase {
  factory DateInputElement() => new InputElement(type: 'date');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'date')).type == 'date';
  }
}

/**
 * A date consisting of a year and a month with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class MonthInputElement implements RangeInputElementBase {
  factory MonthInputElement() => new InputElement(type: 'month');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'month')).type == 'month';
  }
}

/**
 * A date consisting of a week-year number and a week number with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class WeekInputElement implements RangeInputElementBase {
  factory WeekInputElement() => new InputElement(type: 'week');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'week')).type == 'week';
  }
}

/**
 * A time (hour, minute, seconds, fractional seconds) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
abstract class TimeInputElement implements RangeInputElementBase {
  factory TimeInputElement() => new InputElement(type: 'time');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'time')).type == 'time';
  }
}

/**
 * A date and time (year, month, day, hour, minute, second, fraction of a
 * second) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class LocalDateTimeInputElement implements RangeInputElementBase {
  factory LocalDateTimeInputElement() =>
      new InputElement(type: 'datetime-local');

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
  }
}

/**
 * A numeric editor control.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class NumberInputElement implements RangeInputElementBase {
  factory NumberInputElement() => new InputElement(type: 'number');

  String placeholder;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'number')).type == 'number';
  }
}

/**
 * Similar to [NumberInputElement] but the browser may provide more optimal
 * styling (such as a slider control).
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
abstract class RangeInputElement implements RangeInputElementBase {
  factory RangeInputElement() => new InputElement(type: 'range');

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'range')).type == 'range';
  }
}

/**
 * A boolean editor control.
 *
 * Note that if [indeterminate] is set then this control is in a third
 * indeterminate state.
 */
abstract class CheckboxInputElement implements InputElementBase {
  factory CheckboxInputElement() => new InputElement(type: 'checkbox');

  bool checked;

  bool required;
}

/**
 * A control that when used with other [ReadioButtonInputElement] controls
 * forms a radio button group in which only one control can be checked at a
 * time.
 *
 * Radio buttons are considered to be in the same radio button group if:
 *
 * * They are all of type 'radio'.
 * * They all have either the same [FormElement] owner, or no owner.
 * * Their name attributes contain the same name.
 */
abstract class RadioButtonInputElement implements InputElementBase {
  factory RadioButtonInputElement() => new InputElement(type: 'radio');

  bool checked;

  bool required;
}

/**
 * A control for picking files from the user's computer.
 */
abstract class FileUploadInputElement implements InputElementBase {
  factory FileUploadInputElement() => new InputElement(type: 'file');

  String accept;

  bool multiple;

  bool required;

  List<File> files;
}

/**
 * A button, which when clicked, submits the form.
 */
abstract class SubmitButtonInputElement implements InputElementBase {
  factory SubmitButtonInputElement() => new InputElement(type: 'submit');

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;
}

/**
 * Either an image which the user can select a coordinate to or a form
 * submit button.
 */
abstract class ImageButtonInputElement implements InputElementBase {
  factory ImageButtonInputElement() => new InputElement(type: 'image');

  String alt;

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;

  int height;

  String src;

  int width;
}

/**
 * A button, which when clicked, resets the form.
 */
abstract class ResetButtonInputElement implements InputElementBase {
  factory ResetButtonInputElement() => new InputElement(type: 'reset');
}

/**
 * A button, with no default behavior.
 */
abstract class ButtonInputElement implements InputElementBase {
  factory ButtonInputElement() => new InputElement(type: 'button');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("InstallEvent")
class InstallEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory InstallEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return InstallEvent._create_1(type, eventInitDict_1);
    }
    return InstallEvent._create_2(type);
  }
  static InstallEvent _create_1(type, eventInitDict) =>
      JS('InstallEvent', 'new InstallEvent(#,#)', type, eventInitDict);
  static InstallEvent _create_2(type) =>
      JS('InstallEvent', 'new InstallEvent(#)', type);

  void registerForeignFetch(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _registerForeignFetch_1(options_1);
    return;
  }

  @JSName('registerForeignFetch')
  void _registerForeignFetch_1(options) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("IntersectionObserver")
class IntersectionObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory IntersectionObserver(IntersectionObserverCallback callback,
      [Map options]) {
    if (options != null) {
      var callback_1 = convertDartClosureToJS(callback, 2);
      var options_2 = convertDartToNative_Dictionary(options);
      return IntersectionObserver._create_1(callback_1, options_2);
    }
    var callback_1 = convertDartClosureToJS(callback, 2);
    return IntersectionObserver._create_2(callback_1);
  }
  static IntersectionObserver _create_1(callback, options) => JS(
      'IntersectionObserver',
      'new IntersectionObserver(#,#)',
      callback,
      options);
  static IntersectionObserver _create_2(callback) =>
      JS('IntersectionObserver', 'new IntersectionObserver(#)', callback);

  final Element root;

  final String rootMargin;

  final List<num> thresholds;

  void disconnect() native;

  void observe(Element target) native;

  List<IntersectionObserverEntry> takeRecords() native;

  void unobserve(Element target) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void IntersectionObserverCallback(
    List entries, IntersectionObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("IntersectionObserverEntry")
class IntersectionObserverEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  final DomRectReadOnly boundingClientRect;

  final num intersectionRatio;

  final DomRectReadOnly intersectionRect;

  final bool isIntersecting;

  final DomRectReadOnly rootBounds;

  final Element target;

  final num time;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("InterventionReport")
class InterventionReport extends ReportBody {
  // To suppress missing implicit constructor warnings.
  factory InterventionReport._() {
    throw new UnsupportedError("Not supported");
  }

  final int lineNumber;

  final String message;

  final String sourceFile;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An event that describes user interaction with the keyboard.
 *
 * The [type] of the event identifies what kind of interaction occurred.
 *
 * See also:
 *
 * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
 */
@Native("KeyboardEvent")
class KeyboardEvent extends UIEvent {
  /**
   * Programmatically create a KeyboardEvent.
   *
   * Due to browser differences, keyCode, charCode, or keyIdentifier values
   * cannot be specified in this base level constructor. This constructor
   * enables the user to programmatically create and dispatch a [KeyboardEvent],
   * but it will not contain any particular key content. For programmatically
   * creating keyboard events with specific key value contents, see the custom
   * Event [KeyEvent].
   */
  factory KeyboardEvent(String type,
      {Window view,
      bool canBubble: true,
      bool cancelable: true,
      int location,
      int keyLocation, // Legacy alias for location
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    location ??= keyLocation ?? 1;
    KeyboardEvent e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "", location,
        ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }

  void _initKeyboardEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      String keyIdentifier,
      int location,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) {
    if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
      // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
      // a slightly different signature, and allows you to specify keyCode and
      // charCode as the last two arguments, but we just set them as the default
      // since they can't be specified in other browsers.
      JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this, type,
          canBubble, cancelable, view, ctrlKey, altKey, shiftKey, metaKey);
    } else {
      // initKeyboardEvent is for all other browsers.
      JS(
          'void',
          '#.initKeyboardEvent(#, #, #, #, #, #, #, #, #, #)',
          this,
          type,
          canBubble,
          cancelable,
          view,
          keyIdentifier,
          location,
          ctrlKey,
          altKey,
          shiftKey,
          metaKey);
    }
  }

  final int keyCode;

  final int charCode;

  int get which => _which;

  factory KeyboardEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return KeyboardEvent._create_1(type, eventInitDict_1);
    }
    return KeyboardEvent._create_2(type);
  }
  static KeyboardEvent _create_1(type, eventInitDict) =>
      JS('KeyboardEvent', 'new KeyboardEvent(#,#)', type, eventInitDict);
  static KeyboardEvent _create_2(type) =>
      JS('KeyboardEvent', 'new KeyboardEvent(#)', type);

  static const int DOM_KEY_LOCATION_LEFT = 0x01;

  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;

  static const int DOM_KEY_LOCATION_RIGHT = 0x02;

  static const int DOM_KEY_LOCATION_STANDARD = 0x00;

  final bool altKey;

  @JSName('charCode')
  final int _charCode;

  final String code;

  final bool ctrlKey;

  final bool isComposing;

  final String key;

  @JSName('keyCode')
  final int _keyCode;

  final int location;

  final bool metaKey;

  final bool repeat;

  final bool shiftKey;

  bool getModifierState(String keyArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("KeyframeEffect")
class KeyframeEffect extends KeyframeEffectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory KeyframeEffect._() {
    throw new UnsupportedError("Not supported");
  }

  factory KeyframeEffect(Element target, Object effect, [Object options]) {
    if (options != null) {
      return KeyframeEffect._create_1(target, effect, options);
    }
    return KeyframeEffect._create_2(target, effect);
  }
  static KeyframeEffect _create_1(target, effect, options) => JS(
      'KeyframeEffect', 'new KeyframeEffect(#,#,#)', target, effect, options);
  static KeyframeEffect _create_2(target, effect) =>
      JS('KeyframeEffect', 'new KeyframeEffect(#,#)', target, effect);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("KeyframeEffectReadOnly")
class KeyframeEffectReadOnly extends AnimationEffectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory KeyframeEffectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory KeyframeEffectReadOnly(Element target, Object effect,
      [Object options]) {
    if (options != null) {
      return KeyframeEffectReadOnly._create_1(target, effect, options);
    }
    return KeyframeEffectReadOnly._create_2(target, effect);
  }
  static KeyframeEffectReadOnly _create_1(target, effect, options) => JS(
      'KeyframeEffectReadOnly',
      'new KeyframeEffectReadOnly(#,#,#)',
      target,
      effect,
      options);
  static KeyframeEffectReadOnly _create_2(target, effect) => JS(
      'KeyframeEffectReadOnly',
      'new KeyframeEffectReadOnly(#,#)',
      target,
      effect);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLIElement")
class LIElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LIElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LIElement() => JS('returns:LIElement;creates:LIElement;new:true',
      '#.createElement(#)', document, "li");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LIElement.created() : super.created();

  int value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLabelElement")
class LabelElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LabelElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LabelElement() => JS(
      'returns:LabelElement;creates:LabelElement;new:true',
      '#.createElement(#)',
      document,
      "label");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LabelElement.created() : super.created();

  final HtmlElement control;

  final FormElement form;

  String htmlFor;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLegendElement")
class LegendElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LegendElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LegendElement() => JS(
      'returns:LegendElement;creates:LegendElement;new:true',
      '#.createElement(#)',
      document,
      "legend");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LegendElement.created() : super.created();

  final FormElement form;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("LinearAccelerationSensor")
class LinearAccelerationSensor extends Accelerometer {
  // To suppress missing implicit constructor warnings.
  factory LinearAccelerationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory LinearAccelerationSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return LinearAccelerationSensor._create_1(sensorOptions_1);
    }
    return LinearAccelerationSensor._create_2();
  }
  static LinearAccelerationSensor _create_1(sensorOptions) => JS(
      'LinearAccelerationSensor',
      'new LinearAccelerationSensor(#)',
      sensorOptions);
  static LinearAccelerationSensor _create_2() =>
      JS('LinearAccelerationSensor', 'new LinearAccelerationSensor()');
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLinkElement")
class LinkElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LinkElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LinkElement() => JS(
      'returns:LinkElement;creates:LinkElement;new:true',
      '#.createElement(#)',
      document,
      "link");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LinkElement.created() : super.created();

  String as;

  String crossOrigin;

  bool disabled;

  String href;

  String hreflang;

  final Document import;

  String integrity;

  String media;

  String referrerPolicy;

  String rel;

  final DomTokenList relList;

  String scope;

  final StyleSheet sheet;

  final DomTokenList sizes;

  String type;

  /// Checks if HTML imports are supported on the current platform.
  bool get supportsImport {
    return JS('bool', '("import" in #)', this);
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Location")
class Location extends Interceptor implements LocationBase {
  // To suppress missing implicit constructor warnings.
  factory Location._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('DomStringList|Null')
  @Creates('DomStringList')
  final List<String> ancestorOrigins;

  String hash;

  String host;

  String hostname;

  String href;

  String pathname;

  String port;

  String protocol;

  String search;

  TrustedUrl trustedHref;

  void assign([String url]) native;

  void reload() native;

  void replace(String url) native;

  String get origin {
    if (JS('bool', '("origin" in #)', this)) {
      return JS('String', '#.origin', this);
    }
    return '${this.protocol}//${this.host}';
  }

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Magnetometer")
class Magnetometer extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory Magnetometer._() {
    throw new UnsupportedError("Not supported");
  }

  factory Magnetometer([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return Magnetometer._create_1(sensorOptions_1);
    }
    return Magnetometer._create_2();
  }
  static Magnetometer _create_1(sensorOptions) =>
      JS('Magnetometer', 'new Magnetometer(#)', sensorOptions);
  static Magnetometer _create_2() => JS('Magnetometer', 'new Magnetometer()');

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLMapElement")
class MapElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MapElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MapElement() => JS('returns:MapElement;creates:MapElement;new:true',
      '#.createElement(#)', document, "map");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MapElement.created() : super.created();

  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> areas;

  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaCapabilities")
class MediaCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  Future<MediaCapabilitiesInfo> decodingInfo(Map configuration) {
    var configuration_dict = convertDartToNative_Dictionary(configuration);
    return promiseToFuture<MediaCapabilitiesInfo>(
        JS("", "#.decodingInfo(#)", this, configuration_dict));
  }

  Future<MediaCapabilitiesInfo> encodingInfo(Map configuration) {
    var configuration_dict = convertDartToNative_Dictionary(configuration);
    return promiseToFuture<MediaCapabilitiesInfo>(
        JS("", "#.encodingInfo(#)", this, configuration_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaCapabilitiesInfo")
class MediaCapabilitiesInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaCapabilitiesInfo._() {
    throw new UnsupportedError("Not supported");
  }

  final bool powerEfficient;

  final bool smooth;

  final bool supported;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaDeviceInfo")
class MediaDeviceInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaDeviceInfo._() {
    throw new UnsupportedError("Not supported");
  }

  final String deviceId;

  final String groupId;

  final String kind;

  final String label;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaDevices")
class MediaDevices extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaDevices._() {
    throw new UnsupportedError("Not supported");
  }

  Future<List<MediaDeviceInfo>> enumerateDevices() =>
      promiseToFuture<List<MediaDeviceInfo>>(
          JS("", "#.enumerateDevices()", this));

  Map getSupportedConstraints() {
    return convertNativeToDart_Dictionary(_getSupportedConstraints_1());
  }

  @JSName('getSupportedConstraints')
  _getSupportedConstraints_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLMediaElement")
class MediaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MediaElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MediaElement.created() : super.created();

  static const int HAVE_CURRENT_DATA = 2;

  static const int HAVE_ENOUGH_DATA = 4;

  static const int HAVE_FUTURE_DATA = 3;

  static const int HAVE_METADATA = 1;

  static const int HAVE_NOTHING = 0;

  static const int NETWORK_EMPTY = 0;

  static const int NETWORK_IDLE = 1;

  static const int NETWORK_LOADING = 2;

  static const int NETWORK_NO_SOURCE = 3;

  final AudioTrackList audioTracks;

  bool autoplay;

  final TimeRanges buffered;

  bool controls;

  final DomTokenList controlsList;

  String crossOrigin;

  final String currentSrc;

  num currentTime;

  bool defaultMuted;

  num defaultPlaybackRate;

  bool disableRemotePlayback;

  final num duration;

  final bool ended;

  final MediaError error;

  bool loop;

  final MediaKeys mediaKeys;

  bool muted;

  final int networkState;

  final bool paused;

  num playbackRate;

  final TimeRanges played;

  String preload;

  final int readyState;

  final RemotePlayback remote;

  final TimeRanges seekable;

  final bool seeking;

  final String sinkId;

  String src;

  MediaStream srcObject;

  final TextTrackList textTracks;

  final VideoTrackList videoTracks;

  num volume;

  @JSName('webkitAudioDecodedByteCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int audioDecodedByteCount;

  @JSName('webkitVideoDecodedByteCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int videoDecodedByteCount;

  TextTrack addTextTrack(String kind, [String label, String language]) native;

  @Unstable()
  String canPlayType(String type, [String keySystem]) native;

  MediaStream captureStream() native;

  void load() native;

  void pause() native;

  Future play() => promiseToFuture(JS("", "#.play()", this));

  Future setMediaKeys(MediaKeys mediaKeys) =>
      promiseToFuture(JS("", "#.setMediaKeys(#)", this, mediaKeys));

  Future setSinkId(String sinkId) =>
      promiseToFuture(JS("", "#.setSinkId(#)", this, sinkId));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaEncryptedEvent")
class MediaEncryptedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaEncryptedEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaEncryptedEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaEncryptedEvent._create_1(type, eventInitDict_1);
    }
    return MediaEncryptedEvent._create_2(type);
  }
  static MediaEncryptedEvent _create_1(type, eventInitDict) => JS(
      'MediaEncryptedEvent',
      'new MediaEncryptedEvent(#,#)',
      type,
      eventInitDict);
  static MediaEncryptedEvent _create_2(type) =>
      JS('MediaEncryptedEvent', 'new MediaEncryptedEvent(#)', type);

  final ByteBuffer initData;

  final String initDataType;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MediaError")
class MediaError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaError._() {
    throw new UnsupportedError("Not supported");
  }

  static const int MEDIA_ERR_ABORTED = 1;

  static const int MEDIA_ERR_DECODE = 3;

  static const int MEDIA_ERR_NETWORK = 2;

  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  final int code;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeyMessageEvent")
class MediaKeyMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaKeyMessageEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return MediaKeyMessageEvent._create_1(type, eventInitDict_1);
  }
  static MediaKeyMessageEvent _create_1(type, eventInitDict) => JS(
      'MediaKeyMessageEvent',
      'new MediaKeyMessageEvent(#,#)',
      type,
      eventInitDict);

  final ByteBuffer message;

  final String messageType;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeySession")
class MediaKeySession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  Future<void> get closed => promiseToFuture<void>(JS("", "#.closed", this));

  final num expiration;

  final MediaKeyStatusMap keyStatuses;

  final String sessionId;

  Future close() => promiseToFuture(JS("", "#.close()", this));

  Future generateRequest(String initDataType, /*BufferSource*/ initData) =>
      promiseToFuture(
          JS("", "#.generateRequest(#, #)", this, initDataType, initData));

  Future load(String sessionId) =>
      promiseToFuture(JS("", "#.load(#)", this, sessionId));

  Future remove() => promiseToFuture(JS("", "#.remove()", this));

  @JSName('update')
  Future _update(/*BufferSource*/ response) native;

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeyStatusMap")
class MediaKeyStatusMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyStatusMap._() {
    throw new UnsupportedError("Not supported");
  }

  final int size;

  Object get(/*BufferSource*/ keyId) native;

  bool has(/*BufferSource*/ keyId) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeySystemAccess")
class MediaKeySystemAccess extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySystemAccess._() {
    throw new UnsupportedError("Not supported");
  }

  final String keySystem;

  Future createMediaKeys() =>
      promiseToFuture(JS("", "#.createMediaKeys()", this));

  Map getConfiguration() {
    return convertNativeToDart_Dictionary(_getConfiguration_1());
  }

  @JSName('getConfiguration')
  _getConfiguration_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeys")
class MediaKeys extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createSession')
  MediaKeySession _createSession([String sessionType]) native;

  Future getStatusForPolicy(MediaKeysPolicy policy) =>
      promiseToFuture(JS("", "#.getStatusForPolicy(#)", this, policy));

  Future setServerCertificate(/*BufferSource*/ serverCertificate) =>
      promiseToFuture(
          JS("", "#.setServerCertificate(#)", this, serverCertificate));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeysPolicy")
class MediaKeysPolicy extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeysPolicy._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaKeysPolicy(Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return MediaKeysPolicy._create_1(init_1);
  }
  static MediaKeysPolicy _create_1(init) =>
      JS('MediaKeysPolicy', 'new MediaKeysPolicy(#)', init);

  final String minHdcpVersion;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MediaList")
class MediaList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  String mediaText;

  void appendMedium(String medium) native;

  void deleteMedium(String medium) native;

  String item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaMetadata")
class MediaMetadata extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaMetadata._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaMetadata([Map metadata]) {
    if (metadata != null) {
      var metadata_1 = convertDartToNative_Dictionary(metadata);
      return MediaMetadata._create_1(metadata_1);
    }
    return MediaMetadata._create_2();
  }
  static MediaMetadata _create_1(metadata) =>
      JS('MediaMetadata', 'new MediaMetadata(#)', metadata);
  static MediaMetadata _create_2() =>
      JS('MediaMetadata', 'new MediaMetadata()');

  String album;

  String artist;

  List artwork;

  String title;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MediaQueryList")
class MediaQueryList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final bool matches;

  final String media;

  void addListener(EventListener listener) native;

  void removeListener(EventListener listener) native;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaQueryListEvent")
class MediaQueryListEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryListEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaQueryListEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaQueryListEvent._create_1(type, eventInitDict_1);
    }
    return MediaQueryListEvent._create_2(type);
  }
  static MediaQueryListEvent _create_1(type, eventInitDict) => JS(
      'MediaQueryListEvent',
      'new MediaQueryListEvent(#,#)',
      type,
      eventInitDict);
  static MediaQueryListEvent _create_2(type) =>
      JS('MediaQueryListEvent', 'new MediaQueryListEvent(#)', type);

  final bool matches;

  final String media;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaRecorder")
class MediaRecorder extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaRecorder._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  factory MediaRecorder(MediaStream stream, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return MediaRecorder._create_1(stream, options_1);
    }
    return MediaRecorder._create_2(stream);
  }
  static MediaRecorder _create_1(stream, options) =>
      JS('MediaRecorder', 'new MediaRecorder(#,#)', stream, options);
  static MediaRecorder _create_2(stream) =>
      JS('MediaRecorder', 'new MediaRecorder(#)', stream);

  final int audioBitsPerSecond;

  final String mimeType;

  final String state;

  final MediaStream stream;

  final int videoBitsPerSecond;

  static bool isTypeSupported(String type) native;

  void pause() native;

  void requestData() native;

  void resume() native;

  void start([int timeslice]) native;

  void stop() native;

  Stream<Event> get onError => errorEvent.forTarget(this);

  Stream<Event> get onPause => pauseEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaSession")
class MediaSession extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaSession._() {
    throw new UnsupportedError("Not supported");
  }

  MediaMetadata metadata;

  String playbackState;

  void setActionHandler(String action, MediaSessionActionHandler handler)
      native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MediaSessionActionHandler();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaSettingsRange")
class MediaSettingsRange extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaSettingsRange._() {
    throw new UnsupportedError("Not supported");
  }

  final num max;

  final num min;

  final num step;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '11')
@Native("MediaSource")
class MediaSource extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaSource._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaSource() {
    return MediaSource._create_1();
  }
  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.MediaSource)');

  final SourceBufferList activeSourceBuffers;

  num duration;

  final String readyState;

  final SourceBufferList sourceBuffers;

  SourceBuffer addSourceBuffer(String type) native;

  void clearLiveSeekableRange() native;

  void endOfStream([String error]) native;

  static bool isTypeSupported(String type) native;

  void removeSourceBuffer(SourceBuffer buffer) native;

  void setLiveSeekableRange(num start, num end) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStream")
class MediaStream extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaStream._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> addTrackEvent =
      const EventStreamProvider<Event>('addtrack');

  /**
   * Static factory designed to expose `removetrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> removeTrackEvent =
      const EventStreamProvider<Event>('removetrack');

  factory MediaStream([stream_OR_tracks]) {
    if (stream_OR_tracks == null) {
      return MediaStream._create_1();
    }
    if ((stream_OR_tracks is MediaStream)) {
      return MediaStream._create_2(stream_OR_tracks);
    }
    if ((stream_OR_tracks is List<MediaStreamTrack>)) {
      return MediaStream._create_3(stream_OR_tracks);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
  static MediaStream _create_2(stream_OR_tracks) =>
      JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
  static MediaStream _create_3(stream_OR_tracks) =>
      JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);

  final bool active;

  final String id;

  void addTrack(MediaStreamTrack track) native;

  MediaStream clone() native;

  @Creates('JSExtendableArray|MediaStreamTrack')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getAudioTracks() native;

  MediaStreamTrack getTrackById(String trackId) native;

  List<MediaStreamTrack> getTracks() native;

  @Creates('JSExtendableArray|MediaStreamTrack')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getVideoTracks() native;

  void removeTrack(MediaStreamTrack track) native;

  /// Stream of `addtrack` events handled by this [MediaStream].
  Stream<Event> get onAddTrack => addTrackEvent.forTarget(this);

  /// Stream of `removetrack` events handled by this [MediaStream].
  Stream<Event> get onRemoveTrack => removeTrackEvent.forTarget(this);

  /**
   * Checks if the MediaStream APIs are supported on the current platform.
   *
   * See also:
   *
   * * [Navigator.getUserMedia]
   */
  static bool get supported => JS(
      'bool',
      '''!!(#.getUserMedia || #.webkitGetUserMedia ||
        #.mozGetUserMedia || #.msGetUserMedia)''',
      window.navigator,
      window.navigator,
      window.navigator,
      window.navigator);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStreamEvent")
class MediaStreamEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaStreamEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaStreamEvent._create_1(type, eventInitDict_1);
    }
    return MediaStreamEvent._create_2(type);
  }
  static MediaStreamEvent _create_1(type, eventInitDict) =>
      JS('MediaStreamEvent', 'new MediaStreamEvent(#,#)', type, eventInitDict);
  static MediaStreamEvent _create_2(type) =>
      JS('MediaStreamEvent', 'new MediaStreamEvent(#)', type);

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');

  final MediaStream stream;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStreamTrack")
class MediaStreamTrack extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrack._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `mute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> muteEvent =
      const EventStreamProvider<Event>('mute');

  /**
   * Static factory designed to expose `unmute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> unmuteEvent =
      const EventStreamProvider<Event>('unmute');

  String contentHint;

  bool enabled;

  final String id;

  final String kind;

  final String label;

  final bool muted;

  final String readyState;

  Future applyConstraints([Map constraints]) {
    var constraints_dict = null;
    if (constraints != null) {
      constraints_dict = convertDartToNative_Dictionary(constraints);
    }
    return promiseToFuture(
        JS("", "#.applyConstraints(#)", this, constraints_dict));
  }

  MediaStreamTrack clone() native;

  Map getCapabilities() {
    return convertNativeToDart_Dictionary(_getCapabilities_1());
  }

  @JSName('getCapabilities')
  _getCapabilities_1() native;

  Map getConstraints() {
    return convertNativeToDart_Dictionary(_getConstraints_1());
  }

  @JSName('getConstraints')
  _getConstraints_1() native;

  Map getSettings() {
    return convertNativeToDart_Dictionary(_getSettings_1());
  }

  @JSName('getSettings')
  _getSettings_1() native;

  void stop() native;

  /// Stream of `ended` events handled by this [MediaStreamTrack].
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `mute` events handled by this [MediaStreamTrack].
  Stream<Event> get onMute => muteEvent.forTarget(this);

  /// Stream of `unmute` events handled by this [MediaStreamTrack].
  Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStreamTrackEvent")
class MediaStreamTrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaStreamTrackEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return MediaStreamTrackEvent._create_1(type, eventInitDict_1);
  }
  static MediaStreamTrackEvent _create_1(type, eventInitDict) => JS(
      'MediaStreamTrackEvent',
      'new MediaStreamTrackEvent(#,#)',
      type,
      eventInitDict);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      Device.isEventTypeSupported('MediaStreamTrackEvent');

  final MediaStreamTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MemoryInfo")
class MemoryInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() {
    throw new UnsupportedError("Not supported");
  }

  final int jsHeapSizeLimit;

  final int totalJSHeapSize;

  final int usedJSHeapSize;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An HTML <menu> element.
 *
 * A <menu> element represents an unordered list of menu commands.
 *
 * See also:
 *
 *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
 *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
 */
@Native("HTMLMenuElement")
class MenuElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MenuElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MenuElement() => JS(
      'returns:MenuElement;creates:MenuElement;new:true',
      '#.createElement(#)',
      document,
      "menu");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MenuElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MessageCallback(Map message);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MessageChannel")
class MessageChannel extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MessageChannel._() {
    throw new UnsupportedError("Not supported");
  }

  factory MessageChannel() {
    return MessageChannel._create_1();
  }
  static MessageChannel _create_1() =>
      JS('MessageChannel', 'new MessageChannel()');

  final MessagePort port1;

  final MessagePort port2;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("MessageEvent")
class MessageEvent extends Event {
  factory MessageEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Object data,
      String origin,
      String lastEventId,
      Window source,
      List<MessagePort> messagePorts: const []}) {
    if (source == null) {
      source = window;
    }
    if (!Device.isIE) {
      // TODO: This if check should be removed once IE
      // implements the constructor.
      return JS(
          'MessageEvent',
          'new MessageEvent(#, {bubbles: #, cancelable: #, data: #, origin: #, lastEventId: #, source: #, ports: #})',
          type,
          canBubble,
          cancelable,
          data,
          origin,
          lastEventId,
          source,
          messagePorts);
    }
    MessageEvent event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }

  // TODO(alanknight): This really should be generated by the
  // _OutputConversion in the systemnative.py script, but that doesn't
  // use those conversions right now, so do this as a one-off.
  dynamic get data => convertNativeToDart_SerializedScriptValue(this._get_data);

  @JSName('data')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_data;

  factory MessageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MessageEvent._create_1(type, eventInitDict_1);
    }
    return MessageEvent._create_2(type);
  }
  static MessageEvent _create_1(type, eventInitDict) =>
      JS('MessageEvent', 'new MessageEvent(#,#)', type, eventInitDict);
  static MessageEvent _create_2(type) =>
      JS('MessageEvent', 'new MessageEvent(#)', type);

  @Unstable()
  final String lastEventId;

  final String origin;

  @Unstable()
  @Creates('JSExtendableArray')
  final List<MessagePort> ports;

  EventTarget get source => _convertNativeToDart_EventTarget(this._get_source);
  @JSName('source')
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_source;

  final String suborigin;

  void _initMessageEvent(
      String typeArg,
      bool canBubbleArg,
      bool cancelableArg,
      Object dataArg,
      String originArg,
      String lastEventIdArg,
      EventTarget sourceArg,
      List<MessagePort> portsArg) {
    var sourceArg_1 = _convertDartToNative_EventTarget(sourceArg);
    _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
        originArg, lastEventIdArg, sourceArg_1, portsArg);
    return;
  }

  @JSName('initMessageEvent')
  void _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
      originArg, lastEventIdArg, sourceArg, List<MessagePort> portsArg) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("MessagePort")
class MessagePort extends EventTarget {
  void addEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // Messages posted to ports are initially paused, allowing listeners to be
    // setup, start() needs to be explicitly invoked to begin handling messages.
    if (type == 'message') {
      _start();
    }

    super.addEventListener(type, listener, useCapture);
  }

  // To suppress missing implicit constructor warnings.
  factory MessagePort._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [MessagePort].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  void close() native;

  void postMessage(/*any*/ message, [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message) native;

  @JSName('start')
  void _start() native;

  /// Stream of `message` events handled by this [MessagePort].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLMetaElement")
class MetaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MetaElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MetaElement() => JS(
      'returns:MetaElement;creates:MetaElement;new:true',
      '#.createElement(#)',
      document,
      "meta");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MetaElement.created() : super.created();

  String content;

  String httpEquiv;

  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Metadata")
class Metadata extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() {
    throw new UnsupportedError("Not supported");
  }

  DateTime get modificationTime =>
      convertNativeToDart_DateTime(this._get_modificationTime);
  @JSName('modificationTime')
  @Creates('Null')
  final dynamic _get_modificationTime;

  final int size;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MetadataCallback(Metadata metadata);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLMeterElement")
class MeterElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MeterElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MeterElement() => document.createElement("meter");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MeterElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('meter');

  num high;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  num low;

  num max;

  num min;

  num optimum;

  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIAccess")
class MidiAccess extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() {
    throw new UnsupportedError("Not supported");
  }

  final MidiInputMap inputs;

  final MidiOutputMap outputs;

  final bool sysexEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIConnectionEvent")
class MidiConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MidiConnectionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MidiConnectionEvent._create_1(type, eventInitDict_1);
    }
    return MidiConnectionEvent._create_2(type);
  }
  static MidiConnectionEvent _create_1(type, eventInitDict) => JS(
      'MidiConnectionEvent',
      'new MIDIConnectionEvent(#,#)',
      type,
      eventInitDict);
  static MidiConnectionEvent _create_2(type) =>
      JS('MidiConnectionEvent', 'new MIDIConnectionEvent(#)', type);

  final MidiPort port;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIInput")
class MidiInput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiInput._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `midimessage` events to event
   * handlers that are not necessarily instances of [MidiInput].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MidiMessageEvent> midiMessageEvent =
      const EventStreamProvider<MidiMessageEvent>('midimessage');

  /// Stream of `midimessage` events handled by this [MidiInput].
  Stream<MidiMessageEvent> get onMidiMessage =>
      midiMessageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIInputMap")
class MidiInputMap extends Interceptor with MapMixin<String, dynamic> {
  // To suppress missing implicit constructor warnings.
  factory MidiInputMap._() {
    throw new UnsupportedError("Not supported");
  }

  Map _getItem(String key) =>
      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));

  void addAll(Map<String, dynamic> other) {
    throw new UnsupportedError("Not supported");
  }

  bool containsValue(dynamic value) => values.any((e) => e == value);

  bool containsKey(dynamic key) => _getItem(key) != null;

  Map operator [](dynamic key) => _getItem(key);

  void forEach(void f(String key, dynamic value)) {
    var entries = JS('', '#.entries()', this);
    while (true) {
      var entry = JS('', '#.next()', entries);
      if (JS('bool', '#.done', entry)) return;
      f(JS('String', '#.value[0]', entry),
          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<Map> get values {
    final values = <Map>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => JS('int', '#.size', this);

  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  void operator []=(String key, dynamic value) {
    throw new UnsupportedError("Not supported");
  }

  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
    throw new UnsupportedError("Not supported");
  }

  String remove(dynamic key) {
    throw new UnsupportedError("Not supported");
  }

  void clear() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIMessageEvent")
class MidiMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MidiMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MidiMessageEvent._create_1(type, eventInitDict_1);
    }
    return MidiMessageEvent._create_2(type);
  }
  static MidiMessageEvent _create_1(type, eventInitDict) =>
      JS('MidiMessageEvent', 'new MIDIMessageEvent(#,#)', type, eventInitDict);
  static MidiMessageEvent _create_2(type) =>
      JS('MidiMessageEvent', 'new MIDIMessageEvent(#)', type);

  final Uint8List data;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIOutput")
class MidiOutput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiOutput._() {
    throw new UnsupportedError("Not supported");
  }

  void send(Uint8List data, [num timestamp]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIOutputMap")
class MidiOutputMap extends Interceptor with MapMixin<String, dynamic> {
  // To suppress missing implicit constructor warnings.
  factory MidiOutputMap._() {
    throw new UnsupportedError("Not supported");
  }

  Map _getItem(String key) =>
      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));

  void addAll(Map<String, dynamic> other) {
    throw new UnsupportedError("Not supported");
  }

  bool containsValue(dynamic value) => values.any((e) => e == value);

  bool containsKey(dynamic key) => _getItem(key) != null;

  Map operator [](dynamic key) => _getItem(key);

  void forEach(void f(String key, dynamic value)) {
    var entries = JS('', '#.entries()', this);
    while (true) {
      var entry = JS('', '#.next()', entries);
      if (JS('bool', '#.done', entry)) return;
      f(JS('String', '#.value[0]', entry),
          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<Map> get values {
    final values = <Map>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => JS('int', '#.size', this);

  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  void operator []=(String key, dynamic value) {
    throw new UnsupportedError("Not supported");
  }

  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
    throw new UnsupportedError("Not supported");
  }

  String remove(dynamic key) {
    throw new UnsupportedError("Not supported");
  }

  void clear() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIPort")
class MidiPort extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() {
    throw new UnsupportedError("Not supported");
  }

  final String connection;

  final String id;

  final String manufacturer;

  final String name;

  final String state;

  final String type;

  final String version;

  Future close() => promiseToFuture(JS("", "#.close()", this));

  Future open() => promiseToFuture(JS("", "#.open()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MimeType")
class MimeType extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() {
    throw new UnsupportedError("Not supported");
  }

  final String description;

  final Plugin enabledPlugin;

  final String suffixes;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MimeTypeArray")
class MimeTypeArray extends Interceptor
    with ListMixin<MimeType>, ImmutableListMixin<MimeType>
    implements List<MimeType>, JavaScriptIndexingBehavior<MimeType> {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  MimeType operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("MimeType", "#[#]", this, index);
  }

  void operator []=(int index, MimeType value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<MimeType> mixins.
  // MimeType is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  MimeType get first {
    if (this.length > 0) {
      return JS('MimeType', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  MimeType get last {
    int len = this.length;
    if (len > 0) {
      return JS('MimeType', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  MimeType get single {
    int len = this.length;
    if (len == 1) {
      return JS('MimeType', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  MimeType elementAt(int index) => this[index];
  // -- end List<MimeType> mixins.

  MimeType item(int index) native;

  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLModElement")
class ModElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ModElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ModElement.created() : super.created();

  String cite;

  String dateTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MojoWatchCallback(int result);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MouseEvent,DragEvent")
class MouseEvent extends UIEvent {
  factory MouseEvent(String type,
      {Window view,
      int detail: 0,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      int button: 0,
      bool canBubble: true,
      bool cancelable: true,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget relatedTarget}) {
    if (view == null) {
      view = window;
    }
    MouseEvent event = document._createEvent('MouseEvent');
    event._initMouseEvent(
        type,
        canBubble,
        cancelable,
        view,
        detail,
        screenX,
        screenY,
        clientX,
        clientY,
        ctrlKey,
        altKey,
        shiftKey,
        metaKey,
        button,
        relatedTarget);
    return event;
  }

  factory MouseEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MouseEvent._create_1(type, eventInitDict_1);
    }
    return MouseEvent._create_2(type);
  }
  static MouseEvent _create_1(type, eventInitDict) =>
      JS('MouseEvent', 'new MouseEvent(#,#)', type, eventInitDict);
  static MouseEvent _create_2(type) =>
      JS('MouseEvent', 'new MouseEvent(#)', type);

  final bool altKey;

  final int button;

  final int buttons;

  @JSName('clientX')
  final num _clientX;

  @JSName('clientY')
  final num _clientY;

  final bool ctrlKey;

  /**
   * The nonstandard way to access the element that the mouse comes
   * from in the case of a `mouseover` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @deprecated
  final Node fromElement;

  @JSName('layerX')
  final int _layerX;

  @JSName('layerY')
  final int _layerY;

  final bool metaKey;

  @JSName('movementX')
  final int _movementX;

  @JSName('movementY')
  final int _movementY;

  @JSName('pageX')
  final num _pageX;

  @JSName('pageY')
  final num _pageY;

  final String region;

  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @Creates('Node')
  @Returns('EventTarget|=Object|Null')
  final dynamic _get_relatedTarget;

  @JSName('screenX')
  final num _screenX;

  @JSName('screenY')
  final num _screenY;

  final bool shiftKey;

  /**
   * The nonstandard way to access the element that the mouse goes
   * to in the case of a `mouseout` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @deprecated
  final Node toElement;

  bool getModifierState(String keyArg) native;

  void _initMouseEvent(
      String type,
      bool bubbles,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget) {
    var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget);
    _initMouseEvent_1(
        type,
        bubbles,
        cancelable,
        view,
        detail,
        screenX,
        screenY,
        clientX,
        clientY,
        ctrlKey,
        altKey,
        shiftKey,
        metaKey,
        button,
        relatedTarget_1);
    return;
  }

  @JSName('initMouseEvent')
  void _initMouseEvent_1(
      type,
      bubbles,
      cancelable,
      Window view,
      detail,
      screenX,
      screenY,
      clientX,
      clientY,
      ctrlKey,
      altKey,
      shiftKey,
      metaKey,
      button,
      relatedTarget) native;

  Point get client => new Point(_clientX, _clientY);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  Point get movement => new Point(_movementX, _movementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset {
    if (JS('bool', '!!#.offsetX', this)) {
      var x = JS('int', '#.offsetX', this);
      var y = JS('int', '#.offsetY', this);
      return new Point(x, y);
    } else {
      // Firefox does not support offsetX.
      if (!(this.target is Element)) {
        throw new UnsupportedError('offsetX is only supported on elements');
      }
      Element target = this.target;
      var point = (this.client - target.getBoundingClientRect().topLeft);
      return new Point(point.x.toInt(), point.y.toInt());
    }
  }

  Point get screen => new Point(_screenX, _screenY);

  Point get layer => new Point(_layerX, _layerY);

  Point get page => new Point(_pageX, _pageY);

  DataTransfer get dataTransfer =>
      JS('DataTransfer', "#['dataTransfer']", this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MutationCallback(List mutations, MutationObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
@deprecated
@Native("MutationEvent")
class MutationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MutationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  static const int ADDITION = 2;

  static const int MODIFICATION = 1;

  static const int REMOVAL = 3;

  final int attrChange;

  final String attrName;

  final String newValue;

  final String prevValue;

  final Node relatedNode;

  void initMutationEvent(
      String type,
      bool bubbles,
      bool cancelable,
      Node relatedNode,
      String prevValue,
      String newValue,
      String attrName,
      int attrChange) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("MutationObserver,WebKitMutationObserver")
class MutationObserver extends Interceptor {
  void disconnect() native;

  void _observe(Node target, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _observe_1(target, options_1);
      return;
    }
    _observe_2(target);
    return;
  }

  @JSName('observe')
  void _observe_1(Node target, options) native;
  @JSName('observe')
  void _observe_2(Node target) native;

  List<MutationRecord> takeRecords() native;

  /**
   * Checks to see if the mutation observer API is supported on the current
   * platform.
   */
  static bool get supported {
    return JS(
        'bool', '!!(window.MutationObserver || window.WebKitMutationObserver)');
  }

  /**
   * Observes the target for the specified changes.
   *
   * Some requirements for the optional parameters:
   *
   * * Either childList, attributes or characterData must be true.
   * * If attributeOldValue is true then attributes must also be true.
   * * If attributeFilter is specified then attributes must be true.
   * * If characterDataOldValue is true then characterData must be true.
   */
  void observe(Node target,
      {bool childList,
      bool attributes,
      bool characterData,
      bool subtree,
      bool attributeOldValue,
      bool characterDataOldValue,
      List<String> attributeFilter}) {
    // Parse options into map of known type.
    var parsedOptions = _createDict();

    // Override options passed in the map with named optional arguments.
    override(key, value) {
      if (value != null) _add(parsedOptions, key, value);
    }

    override('childList', childList);
    override('attributes', attributes);
    override('characterData', characterData);
    override('subtree', subtree);
    override('attributeOldValue', attributeOldValue);
    override('characterDataOldValue', characterDataOldValue);
    if (attributeFilter != null) {
      override('attributeFilter', _fixupList(attributeFilter));
    }

    _call(target, parsedOptions);
  }

  // TODO: Change to a set when const Sets are available.
  static final _boolKeys = const {
    'childList': true,
    'attributes': true,
    'characterData': true,
    'subtree': true,
    'attributeOldValue': true,
    'characterDataOldValue': true
  };

  static _createDict() => JS('var', '{}');
  static _add(m, String key, value) {
    JS('void', '#[#] = #', m, key, value);
  }

  static _fixupList(list) => list; // TODO: Ensure is a JavaScript Array.

  // Call native function with no conversions.
  @JSName('observe')
  void _call(target, options) native;

  factory MutationObserver(MutationCallback callback) {
    // Dummy statement to mark types as instantiated.
    JS('MutationObserver|MutationRecord', '0');

    return JS(
        'MutationObserver',
        'new(window.MutationObserver||window.WebKitMutationObserver||'
        'window.MozMutationObserver)(#)',
        convertDartClosureToJS(_wrapBinaryZone(callback), 2));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MutationRecord")
class MutationRecord extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> addedNodes;

  final String attributeName;

  final String attributeNamespace;

  final Node nextSibling;

  final String oldValue;

  final Node previousSibling;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> removedNodes;

  final Node target;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigationPreloadManager")
class NavigationPreloadManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigationPreloadManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future disable() => promiseToFuture(JS("", "#.disable()", this));

  Future enable() => promiseToFuture(JS("", "#.enable()", this));

  Future<Map<String, dynamic>> getState() =>
      promiseToFutureAsMap(JS("", "#.getState()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Navigator")
class Navigator extends NavigatorConcurrentHardware
    implements
        NavigatorCookies,
        NavigatorLanguage,
        NavigatorOnLine,
        NavigatorAutomationInformation,
        NavigatorID {
  List<Gamepad> getGamepads() {
    var gamepadList = _getGamepads();

    // If no prototype we need one for the world to hookup to the proper Dart class.
    var jsProto = JS('', '#.prototype', gamepadList);
    if (jsProto == null) {
      JS('', '#.prototype = Object.create(null)', gamepadList);
    }

    applyExtension('GamepadList', gamepadList);
    return gamepadList;
  }

  String get language =>
      JS('String', '#.language || #.userLanguage', this, this);

  /**
   * Gets a stream (video and or audio) from the local computer.
   *
   * Use [MediaStream.supported] to check if this is supported by the current
   * platform. The arguments `audio` and `video` default to `false` (stream does
   * not use audio or video, respectively).
   *
   * Simple example usage:
   *
   *     window.navigator.getUserMedia(audio: true, video: true).then((stream) {
   *       var video = new VideoElement()
   *         ..autoplay = true
   *         ..src = Url.createObjectUrlFromStream(stream);
   *       document.body.append(video);
   *     });
   *
   * The user can also pass in Maps to the audio or video parameters to specify
   * mandatory and optional constraints for the media stream. Not passing in a
   * map, but passing in `true` will provide a MediaStream with audio or
   * video capabilities, but without any additional constraints. The particular
   * constraint names for audio and video are still in flux, but as of this
   * writing, here is an example providing more constraints.
   *
   *     window.navigator.getUserMedia(
   *         audio: true,
   *         video: {'mandatory':
   *                    { 'minAspectRatio': 1.333, 'maxAspectRatio': 1.334 },
   *                 'optional':
   *                    [{ 'minFrameRate': 60 },
   *                     { 'maxWidth': 640 }]
   *     });
   *
   * See also:
   * * [MediaStream.supported]
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  Future<MediaStream> getUserMedia({audio: false, video: false}) {
    var completer = new Completer<MediaStream>();
    var options = {'audio': audio, 'video': video};
    _ensureGetUserMedia();
    this._getUserMedia(convertDartToNative_SerializedScriptValue(options),
        (stream) {
      completer.complete(stream);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  _ensureGetUserMedia() {
    if (JS('bool', '!(#.getUserMedia)', this)) {
      JS(
          'void',
          '#.getUserMedia = '
          '(#.getUserMedia || #.webkitGetUserMedia || #.mozGetUserMedia ||'
          '#.msGetUserMedia)',
          this,
          this,
          this,
          this,
          this);
    }
  }

  @JSName('getUserMedia')
  void _getUserMedia(options, _NavigatorUserMediaSuccessCallback success,
      _NavigatorUserMediaErrorCallback error) native;

  // To suppress missing implicit constructor warnings.
  factory Navigator._() {
    throw new UnsupportedError("Not supported");
  }

  final _BudgetService budget;

  final _Clipboard clipboard;

  final NetworkInformation connection;

  final CredentialsContainer credentials;

  final num deviceMemory;

  final String doNotTrack;

  @Unstable()
  final Geolocation geolocation;

  final int maxTouchPoints;

  final MediaCapabilities mediaCapabilities;

  final MediaDevices mediaDevices;

  final MediaSession mediaSession;

  final MimeTypeArray mimeTypes;

  final _NFC nfc;

  final Permissions permissions;

  final Presentation presentation;

  @Unstable()
  final String productSub;

  final ServiceWorkerContainer serviceWorker;

  final StorageManager storage;

  @Unstable()
  final String vendor;

  @Unstable()
  final String vendorSub;

  final VR vr;

  @JSName('webkitPersistentStorage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final DeprecatedStorageQuota persistentStorage;

  @JSName('webkitTemporaryStorage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final DeprecatedStorageQuota temporaryStorage;

  void cancelKeyboardLock() native;

  Future getBattery() => promiseToFuture(JS("", "#.getBattery()", this));

  @JSName('getGamepads')
  @Returns('_GamepadList|Null')
  @Creates('_GamepadList')
  List<Gamepad> _getGamepads() native;

  Future<RelatedApplication> getInstalledRelatedApps() =>
      promiseToFuture<RelatedApplication>(
          JS("", "#.getInstalledRelatedApps()", this));

  Future getVRDisplays() => promiseToFuture(JS("", "#.getVRDisplays()", this));

  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) native;

  Future requestKeyboardLock([List<String> keyCodes]) {
    if (keyCodes != null) {
      List keyCodes_1 = convertDartToNative_StringArray(keyCodes);
      return _requestKeyboardLock_1(keyCodes_1);
    }
    return _requestKeyboardLock_2();
  }

  @JSName('requestKeyboardLock')
  Future _requestKeyboardLock_1(List keyCodes) =>
      promiseToFuture(JS("", "#.requestKeyboardLock(#)", this, keyCodes));
  @JSName('requestKeyboardLock')
  Future _requestKeyboardLock_2() =>
      promiseToFuture(JS("", "#.requestKeyboardLock()", this));

  @JSName('requestMIDIAccess')
  Future requestMidiAccess([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.requestMidiAccess(#)", this, options_dict));
  }

  Future requestMediaKeySystemAccess(
          String keySystem, List<Map> supportedConfigurations) =>
      promiseToFuture(JS("", "#.requestMediaKeySystemAccess(#, #)", this,
          keySystem, supportedConfigurations));

  bool sendBeacon(String url, Object data) native;

  Future share([Map data]) {
    var data_dict = null;
    if (data != null) {
      data_dict = convertDartToNative_Dictionary(data);
    }
    return promiseToFuture(JS("", "#.share(#)", this, data_dict));
  }

  // From NavigatorAutomationInformation

  final bool webdriver;

  // From NavigatorCookies

  @Unstable()
  final bool cookieEnabled;

  // From NavigatorID

  final String appCodeName;

  final String appName;

  final String appVersion;

  final bool dartEnabled;

  final String platform;

  @Unstable()
  final String product;

  final String userAgent;

  // From NavigatorLanguage

  final List<String> languages;

  // From NavigatorOnLine

  @Unstable()
  final bool onLine;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorAutomationInformation")
class NavigatorAutomationInformation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorAutomationInformation._() {
    throw new UnsupportedError("Not supported");
  }

  final bool webdriver;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorConcurrentHardware")
class NavigatorConcurrentHardware extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorConcurrentHardware._() {
    throw new UnsupportedError("Not supported");
  }

  final int hardwareConcurrency;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorCookies")
class NavigatorCookies extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorCookies._() {
    throw new UnsupportedError("Not supported");
  }

  final bool cookieEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class NavigatorID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorID._() {
    throw new UnsupportedError("Not supported");
  }

  final String appCodeName;

  final String appName;

  final String appVersion;

  final bool dartEnabled;

  final String platform;

  final String product;

  final String userAgent;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class NavigatorLanguage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorLanguage._() {
    throw new UnsupportedError("Not supported");
  }

  final String language;

  final List<String> languages;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class NavigatorOnLine extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorOnLine._() {
    throw new UnsupportedError("Not supported");
  }

  final bool onLine;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorUserMediaError")
class NavigatorUserMediaError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() {
    throw new UnsupportedError("Not supported");
  }

  final String constraintName;

  final String message;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _NavigatorUserMediaErrorCallback(NavigatorUserMediaError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _NavigatorUserMediaSuccessCallback(MediaStream stream);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NetworkInformation")
class NetworkInformation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory NetworkInformation._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final num downlink;

  final num downlinkMax;

  final String effectiveType;

  final int rtt;

  final String type;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Lazy implementation of the child nodes of an element that does not request
 * the actual child nodes of an element until strictly necessary greatly
 * improving performance for the typical cases where it is not required.
 */
class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
  final Node _this;

  _ChildNodeListLazy(this._this);

  Node get first {
    Node result = JS('Node|Null', '#.firstChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Node get last {
    Node result = JS('Node|Null', '#.lastChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Node get single {
    int l = this.length;
    if (l == 0) throw new StateError("No elements");
    if (l > 1) throw new StateError("More than one element");
    return JS('Node|Null', '#.firstChild', _this);
  }

  void add(Node value) {
    _this.append(value);
  }

  void addAll(Iterable<Node> iterable) {
    if (iterable is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = iterable;
      if (!identical(otherList._this, _this)) {
        // Optimized route for copying between nodes.
        for (var i = 0, len = otherList.length; i < len; ++i) {
          _this.append(otherList._this.firstChild);
        }
      }
      return;
    }
    for (Node node in iterable) {
      _this.append(node);
    }
  }

  void insert(int index, Node node) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _this.append(node);
    } else {
      _this.insertBefore(node, this[index]);
    }
  }

  void insertAll(int index, Iterable<Node> iterable) {
    if (index == length) {
      addAll(iterable);
    } else {
      var item = this[index];
      _this.insertAllBefore(iterable, item);
    }
  }

  void setAll(int index, Iterable<Node> iterable) {
    throw new UnsupportedError("Cannot setAll on Node list");
  }

  Node removeLast() {
    final result = last;
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  Node removeAt(int index) {
    var result = this[index];
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  bool remove(Object object) {
    if (object is! Node) return false;
    Node node = object;
    if (!identical(_this, node.parentNode)) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
      [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

  set length(int value) {
    throw new UnsupportedError("Cannot set length on immutable List.");
  }

  Node operator [](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}

@Native("Node")
class Node extends EventTarget {
  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    var copy = value.toList();
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {}
    ;
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() {
    String value = nodeValue; // Fetch DOM Node property once.
    return value == null ? super.toString() : value;
  }

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   *   from MDN.
   */
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> childNodes;

  // To suppress missing implicit constructor warnings.
  factory Node._() {
    throw new UnsupportedError("Not supported");
  }

  static const int ATTRIBUTE_NODE = 2;

  static const int CDATA_SECTION_NODE = 4;

  static const int COMMENT_NODE = 8;

  static const int DOCUMENT_FRAGMENT_NODE = 11;

  static const int DOCUMENT_NODE = 9;

  static const int DOCUMENT_TYPE_NODE = 10;

  static const int ELEMENT_NODE = 1;

  static const int ENTITY_NODE = 6;

  static const int ENTITY_REFERENCE_NODE = 5;

  static const int NOTATION_NODE = 12;

  static const int PROCESSING_INSTRUCTION_NODE = 7;

  static const int TEXT_NODE = 3;

  @JSName('baseURI')
  final String baseUri;

  /**
   * The first child of this node.
   *
   * ## Other resources
   *
   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
   *   from MDN.
   */
  final Node firstChild;

  final bool isConnected;

  /**
   * The last child of this node.
   *
   * ## Other resources
   *
   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
   *   from MDN.
   */
  final Node lastChild;

  @JSName('nextSibling')
  /**
   * The next sibling node.
   *
   * ## Other resources
   *
   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
   *   from MDN.
   */
  final Node nextNode;

  /**
   * The name of this node.
   *
   * This varies by this node's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
   *   from MDN. This page contains a table of [nodeName] values for each
   *   [nodeType].
   */
  final String nodeName;

  /**
   * The type of node.
   *
   * This value is one of:
   *
   * * [ATTRIBUTE_NODE] if this node is an attribute.
   * * [CDATA_SECTION_NODE] if this node is a [CDataSection].
   * * [COMMENT_NODE] if this node is a [Comment].
   * * [DOCUMENT_FRAGMENT_NODE] if this node is a [DocumentFragment].
   * * [DOCUMENT_NODE] if this node is a [Document].
   * * [DOCUMENT_TYPE_NODE] if this node is a [DocumentType] node.
   * * [ELEMENT_NODE] if this node is an [Element].
   * * [ENTITY_NODE] if this node is an entity.
   * * [ENTITY_REFERENCE_NODE] if this node is an entity reference.
   * * [NOTATION_NODE] if this node is a notation.
   * * [PROCESSING_INSTRUCTION_NODE] if this node is a [ProcessingInstruction].
   * * [TEXT_NODE] if this node is a [Text] node.
   *
   * ## Other resources
   *
   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
   *   from MDN.
   */
  final int nodeType;

  /**
   * The value of this node.
   *
   * This varies by this type's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
   *   from MDN. This page contains a table of [nodeValue] values for each
   *   [nodeType].
   */
  final String nodeValue;

  /**
   * The document this node belongs to.
   *
   * Returns null if this node does not belong to any document.
   *
   * ## Other resources
   *
   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
   *   from MDN.
   */
  final Document ownerDocument;

  @JSName('parentElement')
  /**
   * The parent element of this node.
   *
   * Returns null if this node either does not have a parent or its parent is
   * not an element.
   *
   * ## Other resources
   *
   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
   *   from W3C.
   */
  final Element parent;

  /**
   * The parent node of this node.
   *
   * ## Other resources
   *
   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
   *   from MDN.
   */
  final Node parentNode;

  @JSName('previousSibling')
  /**
   * The previous sibling node.
   *
   * ## Other resources
   *
   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
   *   from MDN.
   */
  final Node previousNode;

  @JSName('textContent')
  /**
   * All text within this node and its descendents.
   *
   * ## Other resources
   *
   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
   *   from MDN.
   */
  String text;

  @JSName('appendChild')
  /**
   * Adds a node to the end of the child [nodes] list of this node.
   *
   * If the node already exists in this document, it will be removed from its
   * current parent node, then added to this node.
   *
   * This method is more efficient than `nodes.add`, and is the preferred
   * way of appending a child node.
   */
  Node append(Node node) native;

  @JSName('cloneNode')
  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and descendents are
   * copied as well. If [deep] is `false`, then only this node is copied.
   *
   * ## Other resources
   *
   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
   *   from MDN.
   */
  Node clone(bool deep) native;

  /**
   * Returns true if this node contains the specified node.
   *
   * ## Other resources
   *
   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
   *   from MDN.
   */
  bool contains(Node other) native;

  Node getRootNode([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _getRootNode_1(options_1);
    }
    return _getRootNode_2();
  }

  @JSName('getRootNode')
  Node _getRootNode_1(options) native;
  @JSName('getRootNode')
  Node _getRootNode_2() native;

  /**
   * Returns true if this node has any children.
   *
   * ## Other resources
   *
   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
   *   from MDN.
   */
  bool hasChildNodes() native;

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * ## Other resources
   *
   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
   *   from MDN.
   */
  Node insertBefore(Node node, Node child) native;

  @JSName('removeChild')
  Node _removeChild(Node child) native;

  @JSName('replaceChild')
  Node _replaceChild(Node node, Node child) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("NodeFilter")
class NodeFilter extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NodeFilter._() {
    throw new UnsupportedError("Not supported");
  }

  static const int FILTER_ACCEPT = 1;

  static const int FILTER_REJECT = 2;

  static const int FILTER_SKIP = 3;

  static const int SHOW_ALL = 0xFFFFFFFF;

  static const int SHOW_COMMENT = 0x80;

  static const int SHOW_DOCUMENT = 0x100;

  static const int SHOW_DOCUMENT_FRAGMENT = 0x400;

  static const int SHOW_DOCUMENT_TYPE = 0x200;

  static const int SHOW_ELEMENT = 0x1;

  static const int SHOW_PROCESSING_INSTRUCTION = 0x40;

  static const int SHOW_TEXT = 0x4;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("NodeIterator")
class NodeIterator extends Interceptor {
  factory NodeIterator(Node root, int whatToShow) {
    return document._createNodeIterator(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory NodeIterator._() {
    throw new UnsupportedError("Not supported");
  }

  final bool pointerBeforeReferenceNode;

  final Node referenceNode;

  final Node root;

  final int whatToShow;

  void detach() native;

  Node nextNode() native;

  Node previousNode() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NodeList,RadioNodeList")
class NodeList extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @JSName('item')
  Node _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NonDocumentTypeChildNode")
class NonDocumentTypeChildNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NonDocumentTypeChildNode._() {
    throw new UnsupportedError("Not supported");
  }

  final Element nextElementSibling;

  final Element previousElementSibling;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NonElementParentNode")
class NonElementParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NonElementParentNode._() {
    throw new UnsupportedError("Not supported");
  }

  Element getElementById(String elementId) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NoncedElement")
class NoncedElement extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NoncedElement._() {
    throw new UnsupportedError("Not supported");
  }

  String nonce;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Notification")
class Notification extends EventTarget {
  factory Notification(String title,
      {String dir: null,
      String body: null,
      String lang: null,
      String tag: null,
      String icon: null}) {
    var parsedOptions = {};
    if (dir != null) parsedOptions['dir'] = dir;
    if (body != null) parsedOptions['body'] = body;
    if (lang != null) parsedOptions['lang'] = lang;
    if (tag != null) parsedOptions['tag'] = tag;
    if (icon != null) parsedOptions['icon'] = icon;
    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> clickEvent =
      const EventStreamProvider<Event>('click');

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> closeEvent =
      const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> showEvent =
      const EventStreamProvider<Event>('show');

  static Notification _factoryNotification(String title, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return Notification._create_1(title, options_1);
    }
    return Notification._create_2(title);
  }

  static Notification _create_1(title, options) =>
      JS('Notification', 'new Notification(#,#)', title, options);
  static Notification _create_2(title) =>
      JS('Notification', 'new Notification(#)', title);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.Notification)');

  final List actions;

  final String badge;

  final String body;

  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final Object data;

  final String dir;

  final String icon;

  final String image;

  final String lang;

  static final int maxActions;

  static final String permission;

  final bool renotify;

  final bool requireInteraction;

  final bool silent;

  final String tag;

  final int timestamp;

  final String title;

  final List<int> vibrate;

  void close() native;

  @JSName('requestPermission')
  static Future _requestPermission(
      [_NotificationPermissionCallback deprecatedCallback]) native;

  @JSName('requestPermission')
  static Future<String> requestPermission() {
    var completer = new Completer<String>();
    _requestPermission((value) {
      completer.complete(value);
    });
    return completer.future;
  }

  /// Stream of `click` events handled by this [Notification].
  Stream<Event> get onClick => clickEvent.forTarget(this);

  /// Stream of `close` events handled by this [Notification].
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [Notification].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `show` events handled by this [Notification].
  Stream<Event> get onShow => showEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NotificationEvent")
class NotificationEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory NotificationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory NotificationEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return NotificationEvent._create_1(type, eventInitDict_1);
  }
  static NotificationEvent _create_1(type, eventInitDict) => JS(
      'NotificationEvent', 'new NotificationEvent(#,#)', type, eventInitDict);

  final String action;

  final Notification notification;

  final String reply;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _NotificationPermissionCallback(String permission);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOListElement")
class OListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory OListElement() => JS(
      'returns:OListElement;creates:OListElement;new:true',
      '#.createElement(#)',
      document,
      "ol");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OListElement.created() : super.created();

  bool reversed;

  int start;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLObjectElement")
class ObjectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ObjectElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ObjectElement() => document.createElement("object");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ObjectElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('object');

  WindowBase get contentWindow =>
      _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  String data;

  final FormElement form;

  String height;

  String name;

  String type;

  String useMap;

  final String validationMessage;

  final ValidityState validity;

  String width;

  final bool willValidate;

  Node __getter__(String name) native;

  void __setter__(String name, Node value) native;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OffscreenCanvas")
class OffscreenCanvas extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory OffscreenCanvas._() {
    throw new UnsupportedError("Not supported");
  }

  factory OffscreenCanvas(int width, int height) {
    return OffscreenCanvas._create_1(width, height);
  }
  static OffscreenCanvas _create_1(width, height) =>
      JS('OffscreenCanvas', 'new OffscreenCanvas(#,#)', width, height);

  int height;

  int width;

  Future<Blob> convertToBlob([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<Blob>(
        JS("", "#.convertToBlob(#)", this, options_dict));
  }

  Object getContext(String contextType, [Map attributes]) {
    if (attributes != null) {
      var attributes_1 = convertDartToNative_Dictionary(attributes);
      return _getContext_1(contextType, attributes_1);
    }
    return _getContext_2(contextType);
  }

  @JSName('getContext')
  Object _getContext_1(contextType, attributes) native;
  @JSName('getContext')
  Object _getContext_2(contextType) native;

  ImageBitmap transferToImageBitmap() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OffscreenCanvasRenderingContext2D")
class OffscreenCanvasRenderingContext2D extends Interceptor
    implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory OffscreenCanvasRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  final OffscreenCanvas canvas;

  String direction;

  Object fillStyle;

  String filter;

  String font;

  num globalAlpha;

  String globalCompositeOperation;

  bool imageSmoothingEnabled;

  String imageSmoothingQuality;

  String lineCap;

  num lineDashOffset;

  String lineJoin;

  num lineWidth;

  num miterLimit;

  num shadowBlur;

  String shadowColor;

  num shadowOffsetX;

  num shadowOffsetY;

  Object strokeStyle;

  String textAlign;

  String textBaseline;

  void beginPath() native;

  void clearRect(num x, num y, num width, num height) native;

  void clip([Path2D path]) native;

  Future commit() => promiseToFuture(JS("", "#.commit()", this));

  ImageData createImageData(data_OR_imagedata_OR_sw,
      [int sh_OR_sw,
      imageDataColorSettings_OR_sh,
      Map imageDataColorSettings]) {
    if ((data_OR_imagedata_OR_sw is ImageData) &&
        sh_OR_sw == null &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      var imagedata_1 = convertDartToNative_ImageData(data_OR_imagedata_OR_sw);
      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
    }
    if (sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      return convertNativeToDart_ImageData(
          _createImageData_2(data_OR_imagedata_OR_sw, sh_OR_sw));
    }
    if ((imageDataColorSettings_OR_sh is Map) &&
        sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings == null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings_OR_sh);
      return convertNativeToDart_ImageData(_createImageData_3(
          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_1));
    }
    if (imageDataColorSettings != null &&
        (imageDataColorSettings_OR_sh is int) &&
        sh_OR_sw != null &&
        data_OR_imagedata_OR_sw != null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings);
      return convertNativeToDart_ImageData(_createImageData_4(
          data_OR_imagedata_OR_sw,
          sh_OR_sw,
          imageDataColorSettings_OR_sh,
          imageDataColorSettings_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('createImageData')
  _createImageData_1(imagedata) native;
  @JSName('createImageData')
  _createImageData_2(int sw, sh) native;
  @JSName('createImageData')
  _createImageData_3(int sw, sh, imageDataColorSettings) native;
  @JSName('createImageData')
  _createImageData_4(data, sw, int sh, imageDataColorSettings) native;

  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  CanvasPattern createPattern(
      /*CanvasImageSource*/ image,
      String repetitionType) native;

  CanvasGradient createRadialGradient(
      num x0, num y0, num r0, num x1, num y1, num r1) native;

  void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y,
      [num sw_OR_width,
      num height_OR_sh,
      num dx,
      num dy,
      num dw,
      num dh]) native;

  void fill([path_OR_winding, String winding]) native;

  void fillRect(num x, num y, num width, num height) native;

  void fillText(String text, num x, num y, [num maxWidth]) native;

  ImageData getImageData(int sx, int sy, int sw, int sh) {
    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
  }

  @JSName('getImageData')
  _getImageData_1(sx, sy, sw, sh) native;

  List<num> getLineDash() native;

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
      native;

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  TextMetrics measureText(String text) native;

  void putImageData(ImageData imagedata, int dx, int dy,
      [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) {
    if (dirtyX == null &&
        dirtyY == null &&
        dirtyWidth == null &&
        dirtyHeight == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_1(imagedata_1, dx, dy);
      return;
    }
    if (dirtyHeight != null &&
        dirtyWidth != null &&
        dirtyY != null &&
        dirtyX != null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_2(
          imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('putImageData')
  void _putImageData_1(imagedata, dx, dy) native;
  @JSName('putImageData')
  void _putImageData_2(
      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;

  void resetTransform() native;

  void restore() native;

  void rotate(num angle) native;

  void save() native;

  void scale(num x, num y) native;

  void setLineDash(List<num> dash) native;

  void setTransform(num a, num b, num c, num d, num e, num f) native;

  void stroke([Path2D path]) native;

  void strokeRect(num x, num y, num width, num height) native;

  void strokeText(String text, num x, num y, [num maxWidth]) native;

  void transform(num a, num b, num c, num d, num e, num f) native;

  void translate(num x, num y) native;

  // From CanvasPath

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOptGroupElement")
class OptGroupElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OptGroupElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory OptGroupElement() => JS(
      'returns:OptGroupElement;creates:OptGroupElement;new:true',
      '#.createElement(#)',
      document,
      "optgroup");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptGroupElement.created() : super.created();

  bool disabled;

  String label;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOptionElement")
class OptionElement extends HtmlElement {
  factory OptionElement(
      {String data: '', String value: '', bool selected: false}) {
    return new OptionElement._(data, value, null, selected);
  }

  factory OptionElement._(
      [String data, String value, bool defaultSelected, bool selected]) {
    if (selected != null) {
      return OptionElement._create_1(data, value, defaultSelected, selected);
    }
    if (defaultSelected != null) {
      return OptionElement._create_2(data, value, defaultSelected);
    }
    if (value != null) {
      return OptionElement._create_3(data, value);
    }
    if (data != null) {
      return OptionElement._create_4(data);
    }
    return OptionElement._create_5();
  }
  static OptionElement _create_1(data, value, defaultSelected, selected) => JS(
      'OptionElement',
      'new Option(#,#,#,#)',
      data,
      value,
      defaultSelected,
      selected);
  static OptionElement _create_2(data, value, defaultSelected) =>
      JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
  static OptionElement _create_3(data, value) =>
      JS('OptionElement', 'new Option(#,#)', data, value);
  static OptionElement _create_4(data) =>
      JS('OptionElement', 'new Option(#)', data);
  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptionElement.created() : super.created();

  bool defaultSelected;

  bool disabled;

  final FormElement form;

  final int index;

  String label;

  bool selected;

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OrientationSensor")
class OrientationSensor extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory OrientationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  final List<num> quaternion;

  void populateMatrix(Object targetBuffer) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLOutputElement")
class OutputElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OutputElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory OutputElement() => document.createElement("output");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OutputElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('output');

  String defaultValue;

  final FormElement form;

  final DomTokenList htmlFor;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  String name;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OverconstrainedError")
class OverconstrainedError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory OverconstrainedError._() {
    throw new UnsupportedError("Not supported");
  }

  factory OverconstrainedError(String constraint, String message) {
    return OverconstrainedError._create_1(constraint, message);
  }
  static OverconstrainedError _create_1(constraint, message) => JS(
      'OverconstrainedError',
      'new OverconstrainedError(#,#)',
      constraint,
      message);

  final String constraint;

  final String message;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PageTransitionEvent")
class PageTransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PageTransitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PageTransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PageTransitionEvent._create_1(type, eventInitDict_1);
    }
    return PageTransitionEvent._create_2(type);
  }
  static PageTransitionEvent _create_1(type, eventInitDict) => JS(
      'PageTransitionEvent',
      'new PageTransitionEvent(#,#)',
      type,
      eventInitDict);
  static PageTransitionEvent _create_2(type) =>
      JS('PageTransitionEvent', 'new PageTransitionEvent(#)', type);

  final bool persisted;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaintRenderingContext2D")
class PaintRenderingContext2D extends Interceptor implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory PaintRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  Matrix currentTransform;

  Object fillStyle;

  String filter;

  num globalAlpha;

  String globalCompositeOperation;

  bool imageSmoothingEnabled;

  String imageSmoothingQuality;

  String lineCap;

  num lineDashOffset;

  String lineJoin;

  num lineWidth;

  num miterLimit;

  num shadowBlur;

  String shadowColor;

  num shadowOffsetX;

  num shadowOffsetY;

  Object strokeStyle;

  void beginPath() native;

  void clearRect(num x, num y, num width, num height) native;

  void clip([path_OR_winding, String winding]) native;

  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  CanvasPattern createPattern(
      /*CanvasImageSource*/ image,
      String repetitionType) native;

  CanvasGradient createRadialGradient(
      num x0, num y0, num r0, num x1, num y1, num r1) native;

  void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y,
      [num sw_OR_width,
      num height_OR_sh,
      num dx,
      num dy,
      num dw,
      num dh]) native;

  void fill([path_OR_winding, String winding]) native;

  void fillRect(num x, num y, num width, num height) native;

  List<num> getLineDash() native;

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
      native;

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  void resetTransform() native;

  void restore() native;

  void rotate(num angle) native;

  void save() native;

  void scale(num x, num y) native;

  void setLineDash(List<num> dash) native;

  void setTransform(num a, num b, num c, num d, num e, num f) native;

  void stroke([Path2D path]) native;

  void strokeRect(num x, num y, num width, num height) native;

  void transform(num a, num b, num c, num d, num e, num f) native;

  void translate(num x, num y) native;

  // From CanvasPath

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaintSize")
class PaintSize extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaintSize._() {
    throw new UnsupportedError("Not supported");
  }

  final num height;

  final num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaintWorkletGlobalScope")
class PaintWorkletGlobalScope extends WorkletGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory PaintWorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  final num devicePixelRatio;

  void registerPaint(String name, Object paintCtor) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLParagraphElement")
class ParagraphElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ParagraphElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ParagraphElement() => JS(
      'returns:ParagraphElement;creates:ParagraphElement;new:true',
      '#.createElement(#)',
      document,
      "p");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParagraphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLParamElement")
class ParamElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ParamElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ParamElement() => JS(
      'returns:ParamElement;creates:ParamElement;new:true',
      '#.createElement(#)',
      document,
      "param");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParamElement.created() : super.created();

  String name;

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ParentNode._() {
    throw new UnsupportedError("Not supported");
  }

  final int _childElementCount;

  final List<Node> _children;

  final Element _firstElementChild;

  final Element _lastElementChild;

  Element querySelector(String selectors);

  List<Node> _querySelectorAll(String selectors);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PasswordCredential")
class PasswordCredential extends Credential implements CredentialUserData {
  // To suppress missing implicit constructor warnings.
  factory PasswordCredential._() {
    throw new UnsupportedError("Not supported");
  }

  factory PasswordCredential(data_OR_form) {
    if ((data_OR_form is Map)) {
      var data_1 = convertDartToNative_Dictionary(data_OR_form);
      return PasswordCredential._create_1(data_1);
    }
    if ((data_OR_form is FormElement)) {
      return PasswordCredential._create_2(data_OR_form);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static PasswordCredential _create_1(data_OR_form) =>
      JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form);
  static PasswordCredential _create_2(data_OR_form) =>
      JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form);

  Object additionalData;

  String idName;

  final String password;

  String passwordName;

  // From CredentialUserData

  @JSName('iconURL')
  final String iconUrl;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Path2D")
class Path2D extends Interceptor implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory Path2D._() {
    throw new UnsupportedError("Not supported");
  }

  factory Path2D([path_OR_text]) {
    if (path_OR_text == null) {
      return Path2D._create_1();
    }
    if ((path_OR_text is Path2D)) {
      return Path2D._create_2(path_OR_text);
    }
    if ((path_OR_text is String)) {
      return Path2D._create_3(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Path2D _create_1() => JS('Path2D', 'new Path2D()');
  static Path2D _create_2(path_OR_text) =>
      JS('Path2D', 'new Path2D(#)', path_OR_text);
  static Path2D _create_3(path_OR_text) =>
      JS('Path2D', 'new Path2D(#)', path_OR_text);

  void addPath(Path2D path, [Matrix transform]) native;

  // From CanvasPath

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentAddress")
class PaymentAddress extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentAddress._() {
    throw new UnsupportedError("Not supported");
  }

  final List<String> addressLine;

  final String city;

  final String country;

  final String dependentLocality;

  final String languageCode;

  final String organization;

  final String phone;

  final String postalCode;

  final String recipient;

  final String region;

  final String sortingCode;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentInstruments")
class PaymentInstruments extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentInstruments._() {
    throw new UnsupportedError("Not supported");
  }

  Future clear() => promiseToFuture(JS("", "#.clear()", this));

  Future<bool> delete(String instrumentKey) =>
      promiseToFuture<bool>(JS("", "#.delete(#)", this, instrumentKey));

  Future<Map<String, dynamic>> get(String instrumentKey) =>
      promiseToFutureAsMap(JS("", "#.get(#)", this, instrumentKey));

  Future has(String instrumentKey) =>
      promiseToFuture(JS("", "#.has(#)", this, instrumentKey));

  Future<List<String>> keys() =>
      promiseToFuture<List<String>>(JS("", "#.keys()", this));

  Future set(String instrumentKey, Map details) {
    var details_dict = convertDartToNative_Dictionary(details);
    return promiseToFuture(
        JS("", "#.set(#, #)", this, instrumentKey, details_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentManager")
class PaymentManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentManager._() {
    throw new UnsupportedError("Not supported");
  }

  final PaymentInstruments instruments;

  String userHint;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentRequest")
class PaymentRequest extends EventTarget {
  factory PaymentRequest(List<Map> methodData, Map details, [Map options]) {
    var methodData_1 = [];
    for (var i in methodData) {
      methodData_1.add(convertDartToNative_Dictionary(i));
    }
    if (options != null) {
      var details_1 = convertDartToNative_Dictionary(details);
      var options_2 = convertDartToNative_Dictionary(options);
      return PaymentRequest._create_1(methodData_1, details_1, options_2);
    }
    var details_1 = convertDartToNative_Dictionary(details);
    return PaymentRequest._create_2(methodData_1, details_1);
  }

  static PaymentRequest _create_1(methodData, details, options) => JS(
      'PaymentRequest',
      'new PaymentRequest(#,#,#)',
      methodData,
      details,
      options);
  static PaymentRequest _create_2(methodData, details) =>
      JS('PaymentRequest', 'new PaymentRequest(#,#)', methodData, details);

  // To suppress missing implicit constructor warnings.
  factory PaymentRequest._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final PaymentAddress shippingAddress;

  final String shippingOption;

  final String shippingType;

  Future abort() => promiseToFuture(JS("", "#.abort()", this));

  Future<bool> canMakePayment() =>
      promiseToFuture<bool>(JS("", "#.canMakePayment()", this));

  Future<PaymentResponse> show() =>
      promiseToFuture<PaymentResponse>(JS("", "#.show()", this));
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentRequestEvent")
class PaymentRequestEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PaymentRequestEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PaymentRequestEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PaymentRequestEvent._create_1(type, eventInitDict_1);
  }
  static PaymentRequestEvent _create_1(type, eventInitDict) => JS(
      'PaymentRequestEvent',
      'new PaymentRequestEvent(#,#)',
      type,
      eventInitDict);

  final String instrumentKey;

  final List methodData;

  final List modifiers;

  final String paymentRequestId;

  final String paymentRequestOrigin;

  final String topLevelOrigin;

  final Object total;

  Future<WindowClient> openWindow(String url) =>
      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));

  void respondWith(Future response) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentRequestUpdateEvent")
class PaymentRequestUpdateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PaymentRequestUpdateEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PaymentRequestUpdateEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PaymentRequestUpdateEvent._create_1(type, eventInitDict_1);
    }
    return PaymentRequestUpdateEvent._create_2(type);
  }
  static PaymentRequestUpdateEvent _create_1(type, eventInitDict) => JS(
      'PaymentRequestUpdateEvent',
      'new PaymentRequestUpdateEvent(#,#)',
      type,
      eventInitDict);
  static PaymentRequestUpdateEvent _create_2(type) =>
      JS('PaymentRequestUpdateEvent', 'new PaymentRequestUpdateEvent(#)', type);

  void updateWith(Future detailsPromise) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentResponse")
class PaymentResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentResponse._() {
    throw new UnsupportedError("Not supported");
  }

  final Object details;

  final String methodName;

  final String payerEmail;

  final String payerName;

  final String payerPhone;

  final String requestId;

  final PaymentAddress shippingAddress;

  final String shippingOption;

  Future complete([String paymentResult]) =>
      promiseToFuture(JS("", "#.complete(#)", this, paymentResult));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE)
@Native("Performance")
class Performance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Performance._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.performance)');

  final MemoryInfo memory;

  final PerformanceNavigation navigation;

  final num timeOrigin;

  final PerformanceTiming timing;

  void clearMarks(String markName) native;

  void clearMeasures(String measureName) native;

  void clearResourceTimings() native;

  List<PerformanceEntry> getEntries() native;

  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  List<PerformanceEntry> getEntriesByType(String entryType) native;

  void mark(String markName) native;

  void measure(String measureName, String startMark, String endMark) native;

  double now() native;

  void setResourceTimingBufferSize(int maxSize) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceEntry")
class PerformanceEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() {
    throw new UnsupportedError("Not supported");
  }

  final num duration;

  final String entryType;

  final String name;

  final num startTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceLongTaskTiming")
class PerformanceLongTaskTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceLongTaskTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final List<TaskAttributionTiming> attribution;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceMark")
class PerformanceMark extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMark._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceMeasure")
class PerformanceMeasure extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMeasure._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("PerformanceNavigation")
class PerformanceNavigation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigation._() {
    throw new UnsupportedError("Not supported");
  }

  static const int TYPE_BACK_FORWARD = 2;

  static const int TYPE_NAVIGATE = 0;

  static const int TYPE_RELOAD = 1;

  static const int TYPE_RESERVED = 255;

  final int redirectCount;

  final int type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceNavigationTiming")
class PerformanceNavigationTiming extends PerformanceResourceTiming {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigationTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final num domComplete;

  final num domContentLoadedEventEnd;

  final num domContentLoadedEventStart;

  final num domInteractive;

  final num loadEventEnd;

  final num loadEventStart;

  final int redirectCount;

  final String type;

  final num unloadEventEnd;

  final num unloadEventStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceObserver")
class PerformanceObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory PerformanceObserver(PerformanceObserverCallback callback) {
    var callback_1 = convertDartClosureToJS(callback, 2);
    return PerformanceObserver._create_1(callback_1);
  }
  static PerformanceObserver _create_1(callback) =>
      JS('PerformanceObserver', 'new PerformanceObserver(#)', callback);

  void disconnect() native;

  void observe(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _observe_1(options_1);
    return;
  }

  @JSName('observe')
  void _observe_1(options) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void PerformanceObserverCallback(
    PerformanceObserverEntryList entries, PerformanceObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceObserverEntryList")
class PerformanceObserverEntryList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserverEntryList._() {
    throw new UnsupportedError("Not supported");
  }

  List<PerformanceEntry> getEntries() native;

  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  List<PerformanceEntry> getEntriesByType(String entryType) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformancePaintTiming")
class PerformancePaintTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformancePaintTiming._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceResourceTiming")
class PerformanceResourceTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceResourceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final num connectEnd;

  final num connectStart;

  final int decodedBodySize;

  final num domainLookupEnd;

  final num domainLookupStart;

  final int encodedBodySize;

  final num fetchStart;

  final String initiatorType;

  final String nextHopProtocol;

  final num redirectEnd;

  final num redirectStart;

  final num requestStart;

  final num responseEnd;

  final num responseStart;

  final num secureConnectionStart;

  final List<PerformanceServerTiming> serverTiming;

  final int transferSize;

  final num workerStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceServerTiming")
class PerformanceServerTiming extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceServerTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final String description;

  final num duration;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("PerformanceTiming")
class PerformanceTiming extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final int connectEnd;

  final int connectStart;

  final int domComplete;

  final int domContentLoadedEventEnd;

  final int domContentLoadedEventStart;

  final int domInteractive;

  final int domLoading;

  final int domainLookupEnd;

  final int domainLookupStart;

  final int fetchStart;

  final int loadEventEnd;

  final int loadEventStart;

  final int navigationStart;

  final int redirectEnd;

  final int redirectStart;

  final int requestStart;

  final int responseEnd;

  final int responseStart;

  final int secureConnectionStart;

  final int unloadEventEnd;

  final int unloadEventStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PermissionStatus")
class PermissionStatus extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PermissionStatus._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final String state;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Permissions")
class Permissions extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Permissions._() {
    throw new UnsupportedError("Not supported");
  }

  Future<PermissionStatus> query(Map permission) {
    var permission_dict = convertDartToNative_Dictionary(permission);
    return promiseToFuture<PermissionStatus>(
        JS("", "#.query(#)", this, permission_dict));
  }

  Future<PermissionStatus> request(Map permissions) {
    var permissions_dict = convertDartToNative_Dictionary(permissions);
    return promiseToFuture<PermissionStatus>(
        JS("", "#.request(#)", this, permissions_dict));
  }

  Future<PermissionStatus> requestAll(List<Map> permissions) =>
      promiseToFuture<PermissionStatus>(
          JS("", "#.requestAll(#)", this, permissions));

  Future<PermissionStatus> revoke(Map permission) {
    var permission_dict = convertDartToNative_Dictionary(permission);
    return promiseToFuture<PermissionStatus>(
        JS("", "#.revoke(#)", this, permission_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PhotoCapabilities")
class PhotoCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PhotoCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  final List fillLightMode;

  final MediaSettingsRange imageHeight;

  final MediaSettingsRange imageWidth;

  final String redEyeReduction;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLPictureElement")
class PictureElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PictureElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PictureElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Plugin")
class Plugin extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() {
    throw new UnsupportedError("Not supported");
  }

  final String description;

  final String filename;

  final int length;

  final String name;

  MimeType item(int index) native;

  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PluginArray")
class PluginArray extends Interceptor
    with ListMixin<Plugin>, ImmutableListMixin<Plugin>
    implements JavaScriptIndexingBehavior<Plugin>, List<Plugin> {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Plugin operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Plugin", "#[#]", this, index);
  }

  void operator []=(int index, Plugin value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Plugin> mixins.
  // Plugin is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Plugin get first {
    if (this.length > 0) {
      return JS('Plugin', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Plugin get last {
    int len = this.length;
    if (len > 0) {
      return JS('Plugin', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Plugin get single {
    int len = this.length;
    if (len == 1) {
      return JS('Plugin', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Plugin elementAt(int index) => this[index];
  // -- end List<Plugin> mixins.

  Plugin item(int index) native;

  Plugin namedItem(String name) native;

  void refresh(bool reload) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PointerEvent")
class PointerEvent extends MouseEvent {
  // To suppress missing implicit constructor warnings.
  factory PointerEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PointerEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PointerEvent._create_1(type, eventInitDict_1);
    }
    return PointerEvent._create_2(type);
  }
  static PointerEvent _create_1(type, eventInitDict) =>
      JS('PointerEvent', 'new PointerEvent(#,#)', type, eventInitDict);
  static PointerEvent _create_2(type) =>
      JS('PointerEvent', 'new PointerEvent(#)', type);

  final num height;

  final bool isPrimary;

  final int pointerId;

  final String pointerType;

  final num pressure;

  final num tangentialPressure;

  final int tiltX;

  final int tiltY;

  final int twist;

  final num width;

  List<PointerEvent> getCoalescedEvents() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("PopStateEvent")
class PopStateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PopStateEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PopStateEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PopStateEvent._create_1(type, eventInitDict_1);
    }
    return PopStateEvent._create_2(type);
  }
  static PopStateEvent _create_1(type, eventInitDict) =>
      JS('PopStateEvent', 'new PopStateEvent(#,#)', type, eventInitDict);
  static PopStateEvent _create_2(type) =>
      JS('PopStateEvent', 'new PopStateEvent(#)', type);

  dynamic get state =>
      convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
typedef void _PositionCallback(Geoposition position);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("PositionError")
class PositionError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PositionError._() {
    throw new UnsupportedError("Not supported");
  }

  static const int PERMISSION_DENIED = 1;

  static const int POSITION_UNAVAILABLE = 2;

  static const int TIMEOUT = 3;

  final int code;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
typedef void _PositionErrorCallback(PositionError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLPreElement")
class PreElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PreElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory PreElement() => JS('returns:PreElement;creates:PreElement;new:true',
      '#.createElement(#)', document, "pre");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PreElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Presentation")
class Presentation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Presentation._() {
    throw new UnsupportedError("Not supported");
  }

  PresentationRequest defaultRequest;

  final PresentationReceiver receiver;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationAvailability")
class PresentationAvailability extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationAvailability._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final bool value;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnection")
class PresentationConnection extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnection._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  String binaryType;

  final String id;

  final String state;

  final String url;

  void close() native;

  void send(data_OR_message) native;

  void terminate() native;

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnectionAvailableEvent")
class PresentationConnectionAvailableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionAvailableEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PresentationConnectionAvailableEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PresentationConnectionAvailableEvent._create_1(
        type, eventInitDict_1);
  }
  static PresentationConnectionAvailableEvent _create_1(type, eventInitDict) =>
      JS('PresentationConnectionAvailableEvent',
          'new PresentationConnectionAvailableEvent(#,#)', type, eventInitDict);

  final PresentationConnection connection;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnectionCloseEvent")
class PresentationConnectionCloseEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionCloseEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PresentationConnectionCloseEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PresentationConnectionCloseEvent._create_1(type, eventInitDict_1);
  }
  static PresentationConnectionCloseEvent _create_1(type, eventInitDict) => JS(
      'PresentationConnectionCloseEvent',
      'new PresentationConnectionCloseEvent(#,#)',
      type,
      eventInitDict);

  final String message;

  final String reason;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnectionList")
class PresentationConnectionList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionList._() {
    throw new UnsupportedError("Not supported");
  }

  final List<PresentationConnection> connections;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationReceiver")
class PresentationReceiver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PresentationReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  Future<PresentationConnectionList> get connectionList =>
      promiseToFuture<PresentationConnectionList>(
          JS("", "#.connectionList", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationRequest")
class PresentationRequest extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationRequest._() {
    throw new UnsupportedError("Not supported");
  }

  factory PresentationRequest(url_OR_urls) {
    if ((url_OR_urls is String)) {
      return PresentationRequest._create_1(url_OR_urls);
    }
    if ((url_OR_urls is List<String>)) {
      List urls_1 = convertDartToNative_StringArray(url_OR_urls);
      return PresentationRequest._create_2(urls_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static PresentationRequest _create_1(url_OR_urls) =>
      JS('PresentationRequest', 'new PresentationRequest(#)', url_OR_urls);
  static PresentationRequest _create_2(url_OR_urls) =>
      JS('PresentationRequest', 'new PresentationRequest(#)', url_OR_urls);

  Future<PresentationAvailability> getAvailability() =>
      promiseToFuture<PresentationAvailability>(
          JS("", "#.getAvailability()", this));

  Future<PresentationConnection> reconnect(String id) =>
      promiseToFuture<PresentationConnection>(
          JS("", "#.reconnect(#)", this, id));

  Future<PresentationConnection> start() =>
      promiseToFuture<PresentationConnection>(JS("", "#.start()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("ProcessingInstruction")
class ProcessingInstruction extends CharacterData {
  // To suppress missing implicit constructor warnings.
  factory ProcessingInstruction._() {
    throw new UnsupportedError("Not supported");
  }

  final StyleSheet sheet;

  final String target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLProgressElement")
class ProgressElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ProgressElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ProgressElement() => document.createElement("progress");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ProgressElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('progress');

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  num max;

  final num position;

  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ProgressEvent")
class ProgressEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ProgressEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ProgressEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ProgressEvent._create_1(type, eventInitDict_1);
    }
    return ProgressEvent._create_2(type);
  }
  static ProgressEvent _create_1(type, eventInitDict) =>
      JS('ProgressEvent', 'new ProgressEvent(#,#)', type, eventInitDict);
  static ProgressEvent _create_2(type) =>
      JS('ProgressEvent', 'new ProgressEvent(#)', type);

  final bool lengthComputable;

  final int loaded;

  final int total;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PromiseRejectionEvent")
class PromiseRejectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PromiseRejectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PromiseRejectionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PromiseRejectionEvent._create_1(type, eventInitDict_1);
  }
  static PromiseRejectionEvent _create_1(type, eventInitDict) => JS(
      'PromiseRejectionEvent',
      'new PromiseRejectionEvent(#,#)',
      type,
      eventInitDict);

  Future get promise => promiseToFuture(JS("", "#.promise", this));

  final Object reason;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PublicKeyCredential")
class PublicKeyCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory PublicKeyCredential._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer rawId;

  final AuthenticatorResponse response;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushEvent")
class PushEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PushEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PushEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PushEvent._create_1(type, eventInitDict_1);
    }
    return PushEvent._create_2(type);
  }
  static PushEvent _create_1(type, eventInitDict) =>
      JS('PushEvent', 'new PushEvent(#,#)', type, eventInitDict);
  static PushEvent _create_2(type) => JS('PushEvent', 'new PushEvent(#)', type);

  final PushMessageData data;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushManager")
class PushManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushManager._() {
    throw new UnsupportedError("Not supported");
  }

  static final List<String> supportedContentEncodings;

  Future<PushSubscription> getSubscription() =>
      promiseToFuture<PushSubscription>(JS("", "#.getSubscription()", this));

  Future permissionState([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.permissionState(#)", this, options_dict));
  }

  Future<PushSubscription> subscribe([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<PushSubscription>(
        JS("", "#.subscribe(#)", this, options_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushMessageData")
class PushMessageData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushMessageData._() {
    throw new UnsupportedError("Not supported");
  }

  ByteBuffer arrayBuffer() native;

  Blob blob() native;

  Object json() native;

  String text() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushSubscription")
class PushSubscription extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushSubscription._() {
    throw new UnsupportedError("Not supported");
  }

  final String endpoint;

  final int expirationTime;

  final PushSubscriptionOptions options;

  ByteBuffer getKey(String name) native;

  Future<bool> unsubscribe() =>
      promiseToFuture<bool>(JS("", "#.unsubscribe()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushSubscriptionOptions")
class PushSubscriptionOptions extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushSubscriptionOptions._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer applicationServerKey;

  final bool userVisibleOnly;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLQuoteElement")
class QuoteElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory QuoteElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory QuoteElement() => JS(
      'returns:QuoteElement;creates:QuoteElement;new:true',
      '#.createElement(#)',
      document,
      "q");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  QuoteElement.created() : super.created();

  String cite;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RtcPeerConnectionErrorCallback(DomException exception);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RtcStatsCallback(RtcStatsResponse response);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("Range")
class Range extends Interceptor {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x, point.y);
  // To suppress missing implicit constructor warnings.
  factory Range._() {
    throw new UnsupportedError("Not supported");
  }

  static const int END_TO_END = 2;

  static const int END_TO_START = 3;

  static const int START_TO_END = 1;

  static const int START_TO_START = 0;

  final bool collapsed;

  final Node commonAncestorContainer;

  final Node endContainer;

  final int endOffset;

  final Node startContainer;

  final int startOffset;

  DocumentFragment cloneContents() native;

  Range cloneRange() native;

  void collapse([bool toStart]) native;

  int compareBoundaryPoints(int how, Range sourceRange) native;

  int comparePoint(Node node, int offset) native;

  DocumentFragment createContextualFragment(String fragment) native;

  void deleteContents() native;

  void detach() native;

  void expand(String unit) native;

  DocumentFragment extractContents() native;

  Rectangle getBoundingClientRect() native;

  @JSName('getClientRects')
  @Returns('DomRectList|Null')
  @Creates('DomRectList')
  List<Rectangle> _getClientRects() native;

  void insertNode(Node node) native;

  bool isPointInRange(Node node, int offset) native;

  void selectNode(Node node) native;

  void selectNodeContents(Node node) native;

  void setEnd(Node node, int offset) native;

  void setEndAfter(Node node) native;

  void setEndBefore(Node node) native;

  void setStart(Node node, int offset) native;

  void setStartAfter(Node node) native;

  void setStartBefore(Node node) native;

  void surroundContents(Node newParent) native;

  List<Rectangle> getClientRects() {
    var value = _getClientRects();

    // If no prototype we need one for the world to hookup to the proper Dart class.
    var jsProto = JS('', '#.prototype', value);
    if (jsProto == null) {
      JS('', '#.prototype = Object.create(null)', value);
    }

    applyExtension('DOMRectList', value);

    return value;
  }

  /**
   * Checks if createContextualFragment is supported.
   *
   * See also:
   *
   * * [createContextualFragment]
   */
  static bool get supportsCreateContextualFragment =>
      JS('bool', '("createContextualFragment" in window.Range.prototype)');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RelatedApplication")
class RelatedApplication extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RelatedApplication._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final String platform;

  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RelativeOrientationSensor")
class RelativeOrientationSensor extends OrientationSensor {
  // To suppress missing implicit constructor warnings.
  factory RelativeOrientationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory RelativeOrientationSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return RelativeOrientationSensor._create_1(sensorOptions_1);
    }
    return RelativeOrientationSensor._create_2();
  }
  static RelativeOrientationSensor _create_1(sensorOptions) => JS(
      'RelativeOrientationSensor',
      'new RelativeOrientationSensor(#)',
      sensorOptions);
  static RelativeOrientationSensor _create_2() =>
      JS('RelativeOrientationSensor', 'new RelativeOrientationSensor()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RemotePlayback")
class RemotePlayback extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RemotePlayback._() {
    throw new UnsupportedError("Not supported");
  }

  final String state;

  Future cancelWatchAvailability([int id]) =>
      promiseToFuture(JS("", "#.cancelWatchAvailability(#)", this, id));

  Future prompt() => promiseToFuture(JS("", "#.prompt()", this));

  Future<int> watchAvailability(RemotePlaybackAvailabilityCallback callback) =>
      promiseToFuture<int>(JS("", "#.watchAvailability(#)", this, callback));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RemotePlaybackAvailabilityCallback(bool available);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ReportBody")
class ReportBody extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReportBody._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ReportingObserver")
class ReportingObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReportingObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory ReportingObserver(ReportingObserverCallback callback) {
    var callback_1 = convertDartClosureToJS(callback, 2);
    return ReportingObserver._create_1(callback_1);
  }
  static ReportingObserver _create_1(callback) =>
      JS('ReportingObserver', 'new ReportingObserver(#)', callback);

  void disconnect() native;

  void observe() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void ReportingObserverCallback(
    List reports, ReportingObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RequestAnimationFrameCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ResizeObserver")
class ResizeObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ResizeObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory ResizeObserver(ResizeObserverCallback callback) {
    var callback_1 = convertDartClosureToJS(callback, 2);
    return ResizeObserver._create_1(callback_1);
  }
  static ResizeObserver _create_1(callback) =>
      JS('ResizeObserver', 'new ResizeObserver(#)', callback);

  void disconnect() native;

  void observe(Element target) native;

  void unobserve(Element target) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void ResizeObserverCallback(
    List<ResizeObserverEntry> entries, ResizeObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ResizeObserverEntry")
class ResizeObserverEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ResizeObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  final DomRectReadOnly contentRect;

  final Element target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCCertificate")
class RtcCertificate extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcCertificate._() {
    throw new UnsupportedError("Not supported");
  }

  final int expires;

  List<Map> getFingerprints() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDataChannel,DataChannel")
class RtcDataChannel extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannel._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> closeEvent =
      const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  String binaryType;

  final int bufferedAmount;

  int bufferedAmountLowThreshold;

  final int id;

  final String label;

  final int maxRetransmitTime;

  final int maxRetransmits;

  final bool negotiated;

  final bool ordered;

  final String protocol;

  final String readyState;

  final bool reliable;

  void close() native;

  void send(data) native;

  @JSName('send')
  void sendBlob(Blob data) native;

  @JSName('send')
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  void sendString(String data) native;

  @JSName('send')
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [RtcDataChannel].
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [RtcDataChannel].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [RtcDataChannel].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [RtcDataChannel].
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDataChannelEvent")
class RtcDataChannelEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannelEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcDataChannelEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcDataChannelEvent._create_1(type, eventInitDict_1);
  }
  static RtcDataChannelEvent _create_1(type, eventInitDict) => JS(
      'RtcDataChannelEvent',
      'new RTCDataChannelEvent(#,#)',
      type,
      eventInitDict);

  final RtcDataChannel channel;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDTMFSender")
class RtcDtmfSender extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfSender._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `tonechange` events to event
   * handlers that are not necessarily instances of [RtcDtmfSender].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<RtcDtmfToneChangeEvent> toneChangeEvent =
      const EventStreamProvider<RtcDtmfToneChangeEvent>('tonechange');

  @JSName('canInsertDTMF')
  final bool canInsertDtmf;

  final int duration;

  final int interToneGap;

  final String toneBuffer;

  final MediaStreamTrack track;

  @JSName('insertDTMF')
  void insertDtmf(String tones, [int duration, int interToneGap]) native;

  /// Stream of `tonechange` events handled by this [RtcDtmfSender].
  Stream<RtcDtmfToneChangeEvent> get onToneChange =>
      toneChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDTMFToneChangeEvent")
class RtcDtmfToneChangeEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfToneChangeEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcDtmfToneChangeEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcDtmfToneChangeEvent._create_1(type, eventInitDict_1);
  }
  static RtcDtmfToneChangeEvent _create_1(type, eventInitDict) => JS(
      'RtcDtmfToneChangeEvent',
      'new RTCDTMFToneChangeEvent(#,#)',
      type,
      eventInitDict);

  final String tone;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends Interceptor {
  factory RtcIceCandidate(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS(
        '',
        'window[#]',
        Device.isFirefox
            ? '${Device.propertyPrefix}RTCIceCandidate'
            : 'RTCIceCandidate');
    return JS('RtcIceCandidate', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() {
    throw new UnsupportedError("Not supported");
  }

  String candidate;

  int sdpMLineIndex;

  String sdpMid;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCLegacyStatsReport")
class RtcLegacyStatsReport extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcLegacyStatsReport._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
  @JSName('timestamp')
  final dynamic _get_timestamp;

  final String type;

  List<String> names() native;

  String stat(String name) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection")
class RtcPeerConnection extends EventTarget {
  factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
    var constructorName = JS('RtcPeerConnection', 'window[#]',
        '${Device.propertyPrefix}RTCPeerConnection');
    if (mediaConstraints != null) {
      return JS(
          'RtcPeerConnection',
          'new #(#,#)',
          constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers),
          convertDartToNative_SerializedScriptValue(mediaConstraints));
    } else {
      return JS('RtcPeerConnection', 'new #(#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers));
    }
  }

  /**
   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
   * the current platform.
   */
  static bool get supported {
    // Currently in Firefox some of the RTC elements are defined but throw an
    // error unless the user has specifically enabled them in their
    // about:config. So we have to construct an element to actually test if RTC
    // is supported at the given time.
    try {
      new RtcPeerConnection({
        "iceServers": [
          {"url": "stun:localhost"}
        ]
      });
      return true;
    } catch (_) {
      return false;
    }
    return false;
  }

  /**
  * Temporarily exposes _getStats and old getStats as getLegacyStats until Chrome fully supports
  * new getStats API.
  */
  Future<RtcStatsResponse> getLegacyStats([MediaStreamTrack selector]) {
    var completer = new Completer<RtcStatsResponse>();
    _getStats((value) {
      completer.complete(value);
    }, selector);
    return completer.future;
  }

  @JSName('getStats')
  Future _getStats(
      [RtcStatsCallback successCallback, MediaStreamTrack selector]) native;

  static Future generateCertificate(/*AlgorithmIdentifier*/ keygenAlgorithm) =>
      JS('dynamic', 'generateCertificate(#)', keygenAlgorithm);

  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnection._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addstream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MediaStreamEvent> addStreamEvent =
      const EventStreamProvider<MediaStreamEvent>('addstream');

  /**
   * Static factory designed to expose `datachannel` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent =
      const EventStreamProvider<RtcDataChannelEvent>('datachannel');

  /**
   * Static factory designed to expose `icecandidate` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<RtcPeerConnectionIceEvent>
      iceCandidateEvent =
      const EventStreamProvider<RtcPeerConnectionIceEvent>('icecandidate');

  /**
   * Static factory designed to expose `iceconnectionstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> iceConnectionStateChangeEvent =
      const EventStreamProvider<Event>('iceconnectionstatechange');

  /**
   * Static factory designed to expose `negotiationneeded` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> negotiationNeededEvent =
      const EventStreamProvider<Event>('negotiationneeded');

  /**
   * Static factory designed to expose `removestream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MediaStreamEvent> removeStreamEvent =
      const EventStreamProvider<MediaStreamEvent>('removestream');

  /**
   * Static factory designed to expose `signalingstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> signalingStateChangeEvent =
      const EventStreamProvider<Event>('signalingstatechange');

  final String iceConnectionState;

  final String iceGatheringState;

  final RtcSessionDescription localDescription;

  final RtcSessionDescription remoteDescription;

  final String signalingState;

  Future addIceCandidate(Object candidate,
          [VoidCallback successCallback,
          RtcPeerConnectionErrorCallback failureCallback]) =>
      promiseToFuture(JS("", "#.addIceCandidate(#, #, #)", this, candidate,
          successCallback, failureCallback));

  void addStream(MediaStream stream, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _addStream_1(stream, mediaConstraints_1);
      return;
    }
    _addStream_2(stream);
    return;
  }

  @JSName('addStream')
  void _addStream_1(MediaStream stream, mediaConstraints) native;
  @JSName('addStream')
  void _addStream_2(MediaStream stream) native;

  RtcRtpSender addTrack(MediaStreamTrack track, MediaStream streams) native;

  void close() native;

  Future<RtcSessionDescription> createAnswer([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<RtcSessionDescription>(
        JS("", "#.createAnswer(#)", this, options_dict));
  }

  @JSName('createDTMFSender')
  RtcDtmfSender createDtmfSender(MediaStreamTrack track) native;

  RtcDataChannel createDataChannel(String label, [Map dataChannelDict]) {
    if (dataChannelDict != null) {
      var dataChannelDict_1 = convertDartToNative_Dictionary(dataChannelDict);
      return _createDataChannel_1(label, dataChannelDict_1);
    }
    return _createDataChannel_2(label);
  }

  @JSName('createDataChannel')
  RtcDataChannel _createDataChannel_1(label, dataChannelDict) native;
  @JSName('createDataChannel')
  RtcDataChannel _createDataChannel_2(label) native;

  Future<RtcSessionDescription> createOffer([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<RtcSessionDescription>(
        JS("", "#.createOffer(#)", this, options_dict));
  }

  List<MediaStream> getLocalStreams() native;

  List<RtcRtpReceiver> getReceivers() native;

  List<MediaStream> getRemoteStreams() native;

  List<RtcRtpSender> getSenders() native;

  Future<RtcStatsReport> getStats() =>
      promiseToFuture<RtcStatsReport>(JS("", "#.getStats()", this));

  void removeStream(MediaStream stream) native;

  void removeTrack(RtcRtpSender sender) native;

  void setConfiguration(Map configuration) {
    var configuration_1 = convertDartToNative_Dictionary(configuration);
    _setConfiguration_1(configuration_1);
    return;
  }

  @JSName('setConfiguration')
  void _setConfiguration_1(configuration) native;

  Future setLocalDescription(Map description) {
    var description_dict = convertDartToNative_Dictionary(description);
    return promiseToFuture(
        JS("", "#.setLocalDescription(#)", this, description_dict));
  }

  Future setRemoteDescription(Map description) {
    var description_dict = convertDartToNative_Dictionary(description);
    return promiseToFuture(
        JS("", "#.setRemoteDescription(#)", this, description_dict));
  }

  /// Stream of `addstream` events handled by this [RtcPeerConnection].
  Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);

  /// Stream of `datachannel` events handled by this [RtcPeerConnection].
  Stream<RtcDataChannelEvent> get onDataChannel =>
      dataChannelEvent.forTarget(this);

  /// Stream of `icecandidate` events handled by this [RtcPeerConnection].
  Stream<RtcPeerConnectionIceEvent> get onIceCandidate =>
      iceCandidateEvent.forTarget(this);

  /// Stream of `iceconnectionstatechange` events handled by this [RtcPeerConnection].
  Stream<Event> get onIceConnectionStateChange =>
      iceConnectionStateChangeEvent.forTarget(this);

  /// Stream of `negotiationneeded` events handled by this [RtcPeerConnection].
  Stream<Event> get onNegotiationNeeded =>
      negotiationNeededEvent.forTarget(this);

  /// Stream of `removestream` events handled by this [RtcPeerConnection].
  Stream<MediaStreamEvent> get onRemoveStream =>
      removeStreamEvent.forTarget(this);

  /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
  Stream<Event> get onSignalingStateChange =>
      signalingStateChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCPeerConnectionIceEvent")
class RtcPeerConnectionIceEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnectionIceEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcPeerConnectionIceEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return RtcPeerConnectionIceEvent._create_1(type, eventInitDict_1);
    }
    return RtcPeerConnectionIceEvent._create_2(type);
  }
  static RtcPeerConnectionIceEvent _create_1(type, eventInitDict) => JS(
      'RtcPeerConnectionIceEvent',
      'new RTCPeerConnectionIceEvent(#,#)',
      type,
      eventInitDict);
  static RtcPeerConnectionIceEvent _create_2(type) =>
      JS('RtcPeerConnectionIceEvent', 'new RTCPeerConnectionIceEvent(#)', type);

  final RtcIceCandidate candidate;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCRtpContributingSource")
class RtcRtpContributingSource extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpContributingSource._() {
    throw new UnsupportedError("Not supported");
  }

  final int source;

  final num timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCRtpReceiver")
class RtcRtpReceiver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  final MediaStreamTrack track;

  List<RtcRtpContributingSource> getContributingSources() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCRtpSender")
class RtcRtpSender extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpSender._() {
    throw new UnsupportedError("Not supported");
  }

  final MediaStreamTrack track;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends Interceptor {
  factory RtcSessionDescription(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS(
        '',
        'window[#]',
        Device.isFirefox
            ? '${Device.propertyPrefix}RTCSessionDescription'
            : 'RTCSessionDescription');
    return JS('RtcSessionDescription', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() {
    throw new UnsupportedError("Not supported");
  }

  String sdp;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCStatsReport")
class RtcStatsReport extends Interceptor with MapMixin<String, dynamic> {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() {
    throw new UnsupportedError("Not supported");
  }

  Map _getItem(String key) =>
      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));

  void addAll(Map<String, dynamic> other) {
    throw new UnsupportedError("Not supported");
  }

  bool containsValue(dynamic value) => values.any((e) => e == value);

  bool containsKey(dynamic key) => _getItem(key) != null;

  Map operator [](dynamic key) => _getItem(key);

  void forEach(void f(String key, dynamic value)) {
    var entries = JS('', '#.entries()', this);
    while (true) {
      var entry = JS('', '#.next()', entries);
      if (JS('bool', '#.done', entry)) return;
      f(JS('String', '#.value[0]', entry),
          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<Map> get values {
    final values = <Map>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => JS('int', '#.size', this);

  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  void operator []=(String key, dynamic value) {
    throw new UnsupportedError("Not supported");
  }

  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
    throw new UnsupportedError("Not supported");
  }

  String remove(dynamic key) {
    throw new UnsupportedError("Not supported");
  }

  void clear() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCStatsResponse")
class RtcStatsResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() {
    throw new UnsupportedError("Not supported");
  }

  RtcLegacyStatsReport namedItem(String name) native;

  List<RtcLegacyStatsReport> result() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCTrackEvent")
class RtcTrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcTrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcTrackEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcTrackEvent._create_1(type, eventInitDict_1);
  }
  static RtcTrackEvent _create_1(type, eventInitDict) =>
      JS('RtcTrackEvent', 'new RTCTrackEvent(#,#)', type, eventInitDict);

  final RtcRtpReceiver receiver;

  final List<MediaStream> streams;

  final MediaStreamTrack track;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Screen")
class Screen extends Interceptor {
  Rectangle get available =>
      new Rectangle(_availLeft, _availTop, _availWidth, _availHeight);
  // To suppress missing implicit constructor warnings.
  factory Screen._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('availHeight')
  final int _availHeight;

  @JSName('availLeft')
  final int _availLeft;

  @JSName('availTop')
  final int _availTop;

  @JSName('availWidth')
  final int _availWidth;

  final int colorDepth;

  final int height;

  bool keepAwake;

  final ScreenOrientation orientation;

  final int pixelDepth;

  final int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ScreenOrientation")
class ScreenOrientation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ScreenOrientation._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final int angle;

  final String type;

  Future lock(String orientation) =>
      promiseToFuture(JS("", "#.lock(#)", this, orientation));

  void unlock() native;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLScriptElement")
class ScriptElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ScriptElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ScriptElement() => JS(
      'returns:ScriptElement;creates:ScriptElement;new:true',
      '#.createElement(#)',
      document,
      "script");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ScriptElement.created() : super.created();

  bool async;

  String charset;

  String crossOrigin;

  bool defer;

  String integrity;

  bool noModule;

  String src;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ScrollState")
class ScrollState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ScrollState._() {
    throw new UnsupportedError("Not supported");
  }

  factory ScrollState([Map scrollStateInit]) {
    if (scrollStateInit != null) {
      var scrollStateInit_1 = convertDartToNative_Dictionary(scrollStateInit);
      return ScrollState._create_1(scrollStateInit_1);
    }
    return ScrollState._create_2();
  }
  static ScrollState _create_1(scrollStateInit) =>
      JS('ScrollState', 'new ScrollState(#)', scrollStateInit);
  static ScrollState _create_2() => JS('ScrollState', 'new ScrollState()');

  final num deltaGranularity;

  final num deltaX;

  final num deltaY;

  final bool fromUserInput;

  final bool inInertialPhase;

  final bool isBeginning;

  final bool isDirectManipulation;

  final bool isEnding;

  final int positionX;

  final int positionY;

  final num velocityX;

  final num velocityY;

  void consumeDelta(num x, num y) native;

  void distributeToScrollChainDescendant() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void ScrollStateCallback(ScrollState scrollState);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ScrollTimeline")
class ScrollTimeline extends AnimationTimeline {
  // To suppress missing implicit constructor warnings.
  factory ScrollTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  factory ScrollTimeline([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return ScrollTimeline._create_1(options_1);
    }
    return ScrollTimeline._create_2();
  }
  static ScrollTimeline _create_1(options) =>
      JS('ScrollTimeline', 'new ScrollTimeline(#)', options);
  static ScrollTimeline _create_2() =>
      JS('ScrollTimeline', 'new ScrollTimeline()');

  final String orientation;

  final Element scrollSource;

  final Object timeRange;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SecurityPolicyViolationEvent")
class SecurityPolicyViolationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SecurityPolicyViolationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SecurityPolicyViolationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return SecurityPolicyViolationEvent._create_1(type, eventInitDict_1);
    }
    return SecurityPolicyViolationEvent._create_2(type);
  }
  static SecurityPolicyViolationEvent _create_1(type, eventInitDict) => JS(
      'SecurityPolicyViolationEvent',
      'new SecurityPolicyViolationEvent(#,#)',
      type,
      eventInitDict);
  static SecurityPolicyViolationEvent _create_2(type) => JS(
      'SecurityPolicyViolationEvent',
      'new SecurityPolicyViolationEvent(#)',
      type);

  @JSName('blockedURI')
  final String blockedUri;

  final int columnNumber;

  final String disposition;

  @JSName('documentURI')
  final String documentUri;

  final String effectiveDirective;

  final int lineNumber;

  final String originalPolicy;

  final String referrer;

  final String sample;

  final String sourceFile;

  final int statusCode;

  final String violatedDirective;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSelectElement")
class SelectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SelectElement() => JS(
      'returns:SelectElement;creates:SelectElement;new:true',
      '#.createElement(#)',
      document,
      "select");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SelectElement.created() : super.created();

  bool autofocus;

  bool disabled;

  final FormElement form;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  int length;

  bool multiple;

  String name;

  bool required;

  int selectedIndex;

  int size;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  void __setter__(int index, OptionElement option) native;

  void add(Object element, Object before) native;

  bool checkValidity() native;

  Element item(int index) native;

  OptionElement namedItem(String name) native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;

  // Override default options, since IE returns SelectElement itself and it
  // does not operate as a List.
  List<OptionElement> get options {
    dynamic options = this.querySelectorAll<OptionElement>('option');
    return new UnmodifiableListView(options.toList());
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Selection")
class Selection extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Selection._() {
    throw new UnsupportedError("Not supported");
  }

  final Node anchorNode;

  final int anchorOffset;

  final Node baseNode;

  final int baseOffset;

  final Node extentNode;

  final int extentOffset;

  final Node focusNode;

  final int focusOffset;

  final bool isCollapsed;

  final int rangeCount;

  final String type;

  void addRange(Range range) native;

  void collapse(Node node, [int offset]) native;

  void collapseToEnd() native;

  void collapseToStart() native;

  bool containsNode(Node node, [bool allowPartialContainment]) native;

  void deleteFromDocument() native;

  void empty() native;

  void extend(Node node, [int offset]) native;

  Range getRangeAt(int index) native;

  void modify(String alter, String direction, String granularity) native;

  void removeAllRanges() native;

  void removeRange(Range range) native;

  void selectAllChildren(Node node) native;

  void setBaseAndExtent(
      Node baseNode, int baseOffset, Node extentNode, int extentOffset) native;

  void setPosition(Node node, [int offset]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Sensor")
class Sensor extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Sensor._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  final bool activated;

  final bool hasReading;

  final num timestamp;

  void start() native;

  void stop() native;

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SensorErrorEvent")
class SensorErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SensorErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SensorErrorEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return SensorErrorEvent._create_1(type, eventInitDict_1);
  }
  static SensorErrorEvent _create_1(type, eventInitDict) =>
      JS('SensorErrorEvent', 'new SensorErrorEvent(#,#)', type, eventInitDict);

  final DomException error;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorker")
class ServiceWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorker._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @JSName('scriptURL')
  final String scriptUrl;

  final String state;

  void postMessage(/*any*/ message, [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message) native;

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorkerContainer")
class ServiceWorkerContainer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  final ServiceWorker controller;

  Future<ServiceWorkerRegistration> get ready =>
      promiseToFuture<ServiceWorkerRegistration>(JS("", "#.ready", this));

  Future<ServiceWorkerRegistration> getRegistration([String documentURL]) =>
      promiseToFuture<ServiceWorkerRegistration>(
          JS("", "#.getRegistration(#)", this, documentURL));

  Future<List<ServiceWorkerRegistration>> getRegistrations() =>
      promiseToFuture<List<ServiceWorkerRegistration>>(
          JS("", "#.getRegistrations()", this));

  Future<ServiceWorkerRegistration> register(String url, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<ServiceWorkerRegistration>(
        JS("", "#.register(#, #)", this, url, options_dict));
  }

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorkerGlobalScope")
class ServiceWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> activateEvent =
      const EventStreamProvider<Event>('activate');

  static const EventStreamProvider<Event> fetchEvent =
      const EventStreamProvider<Event>('fetch');

  static const EventStreamProvider<ForeignFetchEvent> foreignfetchEvent =
      const EventStreamProvider<ForeignFetchEvent>('foreignfetch');

  static const EventStreamProvider<Event> installEvent =
      const EventStreamProvider<Event>('install');

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  final Clients clients;

  final ServiceWorkerRegistration registration;

  Future skipWaiting() => promiseToFuture(JS("", "#.skipWaiting()", this));

  Stream<Event> get onActivate => activateEvent.forTarget(this);

  Stream<Event> get onFetch => fetchEvent.forTarget(this);

  Stream<ForeignFetchEvent> get onForeignfetch =>
      foreignfetchEvent.forTarget(this);

  Stream<Event> get onInstall => installEvent.forTarget(this);

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  static ServiceWorkerGlobalScope get instance {
    return _workerSelf as ServiceWorkerGlobalScope;
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorkerRegistration")
class ServiceWorkerRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerRegistration._() {
    throw new UnsupportedError("Not supported");
  }

  final ServiceWorker active;

  final BackgroundFetchManager backgroundFetch;

  final ServiceWorker installing;

  final NavigationPreloadManager navigationPreload;

  final PaymentManager paymentManager;

  final PushManager pushManager;

  final String scope;

  final SyncManager sync;

  final ServiceWorker waiting;

  Future<List<Notification>> getNotifications([Map filter]) {
    var filter_dict = null;
    if (filter != null) {
      filter_dict = convertDartToNative_Dictionary(filter);
    }
    return promiseToFuture<List<Notification>>(
        JS("", "#.getNotifications(#)", this, filter_dict));
  }

  Future showNotification(String title, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.showNotification(#, #)", this, title, options_dict));
  }

  Future<bool> unregister() =>
      promiseToFuture<bool>(JS("", "#.unregister()", this));

  Future update() => promiseToFuture(JS("", "#.update()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Native("HTMLShadowElement")
class ShadowElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ShadowElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ShadowElement() => document.createElement("shadow");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ShadowElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('shadow');

  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Native("ShadowRoot")
class ShadowRoot extends DocumentFragment implements DocumentOrShadowRoot {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() {
    throw new UnsupportedError("Not supported");
  }

  final bool delegatesFocus;

  final Element host;

  @JSName('innerHTML')
  String innerHtml;

  final String mode;

  final ShadowRoot olderShadowRoot;

  // From DocumentOrShadowRoot

  final Element activeElement;

  final Element fullscreenElement;

  final Element pointerLockElement;

  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> styleSheets;

  Element elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  Selection getSelection() native;

  static bool get supported => JS(
      'bool',
      '!!(Element.prototype.createShadowRoot||'
      'Element.prototype.webkitCreateShadowRoot)');

  static bool _shadowRootDeprecationReported = false;
  static void _shadowRootDeprecationReport() {
    if (!_shadowRootDeprecationReported) {
      window.console.warn('''
ShadowRoot.resetStyleInheritance and ShadowRoot.applyAuthorStyles now deprecated in dart:html.
Please remove them from your code.
''');
      _shadowRootDeprecationReported = true;
    }
  }

  @deprecated
  bool get resetStyleInheritance {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set applyAuthorStyles(bool value) {
    _shadowRootDeprecationReport();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SharedArrayBuffer")
class SharedArrayBuffer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SharedArrayBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  final int byteLength;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SharedWorker")
class SharedWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory SharedWorker._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  factory SharedWorker(String scriptURL, [String name]) {
    if (name != null) {
      return SharedWorker._create_1(scriptURL, name);
    }
    return SharedWorker._create_2(scriptURL);
  }
  static SharedWorker _create_1(scriptURL, name) =>
      JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
  static SharedWorker _create_2(scriptURL) =>
      JS('SharedWorker', 'new SharedWorker(#)', scriptURL);

  final MessagePort port;

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SharedWorkerGlobalScope")
class SharedWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory SharedWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [SharedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> connectEvent =
      const EventStreamProvider<Event>('connect');

  static const int PERSISTENT = 1;

  static const int TEMPORARY = 0;

  final String name;

  void close() native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitRequestFileSystem(int type, int size,
      [_FileSystemCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystemSync')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitResolveLocalFileSystemUrl(
      String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  /// Stream of `connect` events handled by this [SharedWorkerGlobalScope].
  Stream<Event> get onConnect => connectEvent.forTarget(this);

  static SharedWorkerGlobalScope get instance {
    return _workerSelf as SharedWorkerGlobalScope;
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSlotElement")
class SlotElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SlotElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SlotElement.created() : super.created();

  String name;

  List<Node> assignedNodes([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _assignedNodes_1(options_1);
    }
    return _assignedNodes_2();
  }

  @JSName('assignedNodes')
  List<Node> _assignedNodes_1(options) native;
  @JSName('assignedNodes')
  List<Node> _assignedNodes_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SourceBuffer")
class SourceBuffer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SourceBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  num appendWindowEnd;

  num appendWindowStart;

  final AudioTrackList audioTracks;

  final TimeRanges buffered;

  String mode;

  num timestampOffset;

  TrackDefaultList trackDefaults;

  final bool updating;

  final VideoTrackList videoTracks;

  void abort() native;

  void appendBuffer(ByteBuffer data) native;

  @JSName('appendBuffer')
  void appendTypedData(TypedData data) native;

  void remove(num start, num end) native;

  Stream<Event> get onAbort => abortEvent.forTarget(this);

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SourceBufferList")
class SourceBufferList extends EventTarget
    with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer>
    implements JavaScriptIndexingBehavior<SourceBuffer>, List<SourceBuffer> {
  // To suppress missing implicit constructor warnings.
  factory SourceBufferList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  SourceBuffer operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SourceBuffer", "#[#]", this, index);
  }

  void operator []=(int index, SourceBuffer value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SourceBuffer> mixins.
  // SourceBuffer is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SourceBuffer get first {
    if (this.length > 0) {
      return JS('SourceBuffer', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get last {
    int len = this.length;
    if (len > 0) {
      return JS('SourceBuffer', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get single {
    int len = this.length;
    if (len == 1) {
      return JS('SourceBuffer', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SourceBuffer elementAt(int index) => this[index];
  // -- end List<SourceBuffer> mixins.

  SourceBuffer item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSourceElement")
class SourceElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SourceElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SourceElement() => JS(
      'returns:SourceElement;creates:SourceElement;new:true',
      '#.createElement(#)',
      document,
      "source");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SourceElement.created() : super.created();

  String media;

  String sizes;

  String src;

  String srcset;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSpanElement")
class SpanElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SpanElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpanElement() => JS(
      'returns:SpanElement;creates:SpanElement;new:true',
      '#.createElement(#)',
      document,
      "span");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SpanElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechGrammar")
class SpeechGrammar extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammar._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechGrammar() {
    return SpeechGrammar._create_1();
  }
  static SpeechGrammar _create_1() =>
      JS('SpeechGrammar', 'new SpeechGrammar()');

  String src;

  num weight;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechGrammarList")
class SpeechGrammarList extends Interceptor
    with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar>
    implements JavaScriptIndexingBehavior<SpeechGrammar>, List<SpeechGrammar> {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammarList._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechGrammarList() {
    return SpeechGrammarList._create_1();
  }
  static SpeechGrammarList _create_1() =>
      JS('SpeechGrammarList', 'new SpeechGrammarList()');

  int get length => JS("int", "#.length", this);

  SpeechGrammar operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SpeechGrammar", "#[#]", this, index);
  }

  void operator []=(int index, SpeechGrammar value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechGrammar> mixins.
  // SpeechGrammar is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechGrammar get first {
    if (this.length > 0) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechGrammar', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechGrammar elementAt(int index) => this[index];
  // -- end List<SpeechGrammar> mixins.

  void addFromString(String string, [num weight]) native;

  void addFromUri(String src, [num weight]) native;

  SpeechGrammar item(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognition")
class SpeechRecognition extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognition._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `audioend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> audioEndEvent =
      const EventStreamProvider<Event>('audioend');

  /**
   * Static factory designed to expose `audiostart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> audioStartEvent =
      const EventStreamProvider<Event>('audiostart');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> endEvent =
      const EventStreamProvider<Event>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechRecognitionError> errorEvent =
      const EventStreamProvider<SpeechRecognitionError>('error');

  /**
   * Static factory designed to expose `nomatch` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent =
      const EventStreamProvider<SpeechRecognitionEvent>('nomatch');

  /**
   * Static factory designed to expose `result` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechRecognitionEvent> resultEvent =
      const EventStreamProvider<SpeechRecognitionEvent>('result');

  /**
   * Static factory designed to expose `soundend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> soundEndEvent =
      const EventStreamProvider<Event>('soundend');

  /**
   * Static factory designed to expose `soundstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> soundStartEvent =
      const EventStreamProvider<Event>('soundstart');

  /**
   * Static factory designed to expose `speechend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> speechEndEvent =
      const EventStreamProvider<Event>('speechend');

  /**
   * Static factory designed to expose `speechstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> speechStartEvent =
      const EventStreamProvider<Event>('speechstart');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> startEvent =
      const EventStreamProvider<Event>('start');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS(
      'bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');

  MediaStreamTrack audioTrack;

  bool continuous;

  SpeechGrammarList grammars;

  bool interimResults;

  String lang;

  int maxAlternatives;

  void abort() native;

  void start() native;

  void stop() native;

  /// Stream of `audioend` events handled by this [SpeechRecognition].
  Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);

  /// Stream of `audiostart` events handled by this [SpeechRecognition].
  Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechRecognition].
  Stream<Event> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechRecognition].
  Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);

  /// Stream of `nomatch` events handled by this [SpeechRecognition].
  Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);

  /// Stream of `result` events handled by this [SpeechRecognition].
  Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);

  /// Stream of `soundend` events handled by this [SpeechRecognition].
  Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);

  /// Stream of `soundstart` events handled by this [SpeechRecognition].
  Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);

  /// Stream of `speechend` events handled by this [SpeechRecognition].
  Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);

  /// Stream of `speechstart` events handled by this [SpeechRecognition].
  Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechRecognition].
  Stream<Event> get onStart => startEvent.forTarget(this);

  factory SpeechRecognition() {
    return JS('SpeechRecognition',
        'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionAlternative")
class SpeechRecognitionAlternative extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() {
    throw new UnsupportedError("Not supported");
  }

  final num confidence;

  final String transcript;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionError")
class SpeechRecognitionError extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionError._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechRecognitionError(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return SpeechRecognitionError._create_1(type, initDict_1);
    }
    return SpeechRecognitionError._create_2(type);
  }
  static SpeechRecognitionError _create_1(type, initDict) => JS(
      'SpeechRecognitionError',
      'new SpeechRecognitionError(#,#)',
      type,
      initDict);
  static SpeechRecognitionError _create_2(type) =>
      JS('SpeechRecognitionError', 'new SpeechRecognitionError(#)', type);

  final String error;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionEvent")
class SpeechRecognitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechRecognitionEvent(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return SpeechRecognitionEvent._create_1(type, initDict_1);
    }
    return SpeechRecognitionEvent._create_2(type);
  }
  static SpeechRecognitionEvent _create_1(type, initDict) => JS(
      'SpeechRecognitionEvent',
      'new SpeechRecognitionEvent(#,#)',
      type,
      initDict);
  static SpeechRecognitionEvent _create_2(type) =>
      JS('SpeechRecognitionEvent', 'new SpeechRecognitionEvent(#)', type);

  final Document emma;

  final Document interpretation;

  final int resultIndex;

  @Returns('_SpeechRecognitionResultList|Null')
  @Creates('_SpeechRecognitionResultList')
  final List<SpeechRecognitionResult> results;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionResult")
class SpeechRecognitionResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() {
    throw new UnsupportedError("Not supported");
  }

  final bool isFinal;

  final int length;

  SpeechRecognitionAlternative item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesis")
class SpeechSynthesis extends EventTarget {
  List<SpeechSynthesisVoice> getVoices() {
    List<SpeechSynthesisVoice> voices = _getVoices();
    if (voices.length > 0) applyExtension('SpeechSynthesisVoice', voices[0]);
    return voices;
  }

  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesis._() {
    throw new UnsupportedError("Not supported");
  }

  final bool paused;

  final bool pending;

  final bool speaking;

  void cancel() native;

  @JSName('getVoices')
  List<SpeechSynthesisVoice> _getVoices() native;

  void pause() native;

  void resume() native;

  void speak(SpeechSynthesisUtterance utterance) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesisEvent")
class SpeechSynthesisEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisEvent._() {
    throw new UnsupportedError("Not supported");
  }

  final int charIndex;

  final num elapsedTime;

  final String name;

  final SpeechSynthesisUtterance utterance;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesisUtterance")
class SpeechSynthesisUtterance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisUtterance._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `boundary` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> boundaryEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('boundary');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> endEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `mark` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> markEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('mark');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `resume` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> resumeEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('resume');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> startEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('start');

  factory SpeechSynthesisUtterance([String text]) {
    if (text != null) {
      return SpeechSynthesisUtterance._create_1(text);
    }
    return SpeechSynthesisUtterance._create_2();
  }
  static SpeechSynthesisUtterance _create_1(text) =>
      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance(#)', text);
  static SpeechSynthesisUtterance _create_2() =>
      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance()');

  String lang;

  num pitch;

  num rate;

  String text;

  SpeechSynthesisVoice voice;

  num volume;

  /// Stream of `boundary` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onBoundary => boundaryEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechSynthesisUtterance].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `mark` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onMark => markEvent.forTarget(this);

  /// Stream of `pause` events handled by this [SpeechSynthesisUtterance].
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  /// Stream of `resume` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onResume => resumeEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onStart => startEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesisVoice")
class SpeechSynthesisVoice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('default')
  final bool defaultValue;

  final String lang;

  final bool localService;

  final String name;

  @JSName('voiceURI')
  final String voiceUri;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StaticRange")
class StaticRange extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StaticRange._() {
    throw new UnsupportedError("Not supported");
  }

  final bool collapsed;

  final Node endContainer;

  final int endOffset;

  final Node startContainer;

  final int startOffset;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * The type used by the
 * [Window.localStorage] and [Window.sessionStorage] properties.
 * Storage is implemented as a Map&lt;String, String>.
 *
 * To store and get values, use Dart's built-in map syntax:
 *
 *     window.localStorage['key1'] = 'val1';
 *     window.localStorage['key2'] = 'val2';
 *     window.localStorage['key3'] = 'val3';
 *     assert(window.localStorage['key3'] == 'val3');
 *
 * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 * For more examples of using this API, see
 * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
 * For details on using the Map API, see the
 * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
 * section of the library tour.
 */
@Unstable()
@Native("Storage")
class Storage extends Interceptor with MapMixin<String, String> {
  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(Object value) => values.any((e) => e == value);

  bool containsKey(Object key) => _getItem(key) != null;

  String operator [](Object key) => _getItem(key);

  void operator []=(String key, String value) {
    _setItem(key, value);
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(Object key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('length')
  final int _length;

  @JSName('clear')
  void _clear() native;

  @JSName('getItem')
  String _getItem(String key) native;

  @JSName('key')
  String _key(int index) native;

  @JSName('removeItem')
  void _removeItem(String key) native;

  @JSName('setItem')
  void _setItem(String key, String value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void StorageErrorCallback(DomError error);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("StorageEvent")
class StorageEvent extends Event {
  factory StorageEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      String key,
      String oldValue,
      String newValue,
      String url,
      Storage storageArea}) {
    StorageEvent e = document._createEvent("StorageEvent");
    e._initStorageEvent(
        type, canBubble, cancelable, key, oldValue, newValue, url, storageArea);
    return e;
  }

  factory StorageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return StorageEvent._create_1(type, eventInitDict_1);
    }
    return StorageEvent._create_2(type);
  }
  static StorageEvent _create_1(type, eventInitDict) =>
      JS('StorageEvent', 'new StorageEvent(#,#)', type, eventInitDict);
  static StorageEvent _create_2(type) =>
      JS('StorageEvent', 'new StorageEvent(#)', type);

  final String key;

  final String newValue;

  final String oldValue;

  final Storage storageArea;

  final String url;

  @JSName('initStorageEvent')
  void _initStorageEvent(
      String typeArg,
      bool canBubbleArg,
      bool cancelableArg,
      String keyArg,
      String oldValueArg,
      String newValueArg,
      String urlArg,
      Storage storageAreaArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StorageManager")
class StorageManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StorageManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<Map<String, dynamic>> estimate() =>
      promiseToFutureAsMap(JS("", "#.estimate()", this));

  Future<bool> persist() => promiseToFuture<bool>(JS("", "#.persist()", this));

  Future<bool> persisted() =>
      promiseToFuture<bool>(JS("", "#.persisted()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void StorageQuotaCallback(int grantedQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void StorageUsageCallback(
    int currentUsageInBytes, int currentQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLStyleElement")
class StyleElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory StyleElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory StyleElement() => JS(
      'returns:StyleElement;creates:StyleElement;new:true',
      '#.createElement(#)',
      document,
      "style");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  StyleElement.created() : super.created();

  bool disabled;

  String media;

  final StyleSheet sheet;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StyleMedia")
class StyleMedia extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() {
    throw new UnsupportedError("Not supported");
  }

  final String type;

  bool matchMedium(String mediaquery) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StylePropertyMap")
class StylePropertyMap extends StylePropertyMapReadonly {
  // To suppress missing implicit constructor warnings.
  factory StylePropertyMap._() {
    throw new UnsupportedError("Not supported");
  }

  void append(String property, Object value) native;

  void delete(String property) native;

  void set(String property, Object value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StylePropertyMapReadonly")
class StylePropertyMapReadonly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StylePropertyMapReadonly._() {
    throw new UnsupportedError("Not supported");
  }

  CssStyleValue get(String property) native;

  List<CssStyleValue> getAll(String property) native;

  List<String> getProperties() native;

  bool has(String property) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StyleSheet")
class StyleSheet extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  bool disabled;

  final String href;

  final MediaList media;

  final Node ownerNode;

  final StyleSheet parentStyleSheet;

  final String title;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SyncEvent")
class SyncEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory SyncEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SyncEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return SyncEvent._create_1(type, init_1);
  }
  static SyncEvent _create_1(type, init) =>
      JS('SyncEvent', 'new SyncEvent(#,#)', type, init);

  final bool lastChance;

  final String tag;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SyncManager")
class SyncManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SyncManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<List<String>> getTags() =>
      promiseToFuture<List<String>>(JS("", "#.getTags()", this));

  Future register(String tag) =>
      promiseToFuture(JS("", "#.register(#)", this, tag));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableCaptionElement")
class TableCaptionElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableCaptionElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableCaptionElement() => JS(
      'returns:TableCaptionElement;creates:TableCaptionElement;new:true',
      '#.createElement(#)',
      document,
      "caption");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCaptionElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native(
    "HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement")
class TableCellElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableCellElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableCellElement() => JS(
      'returns:TableCellElement;creates:TableCellElement;new:true',
      '#.createElement(#)',
      document,
      "td");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCellElement.created() : super.created();

  final int cellIndex;

  int colSpan;

  String headers;

  int rowSpan;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableColElement")
class TableColElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableColElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableColElement() => JS(
      'returns:TableColElement;creates:TableColElement;new:true',
      '#.createElement(#)',
      document,
      "col");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableColElement.created() : super.created();

  int span;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableElement")
class TableElement extends HtmlElement {
  List<TableSectionElement> get tBodies =>
      new _WrappedList<TableSectionElement>(_tBodies);

  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableCaptionElement createCaption() => _createCaption();
  TableSectionElement createTBody() => _createTBody();
  TableSectionElement createTFoot() => _createTFoot();
  TableSectionElement createTHead() => _createTHead();
  TableRowElement insertRow(int index) => _insertRow(index);

  TableSectionElement _createTBody() {
    if (JS('bool', '!!#.createTBody', this)) {
      return this._nativeCreateTBody();
    }
    var tbody = new Element.tag('tbody');
    this.children.add(tbody);
    return tbody;
  }

  @JSName('createTBody')
  TableSectionElement _nativeCreateTBody() native;

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var contextualHtml = '<table>$html</table>';
    var table = new Element.html(contextualHtml,
        validator: validator, treeSanitizer: treeSanitizer);
    var fragment = new DocumentFragment();
    fragment.nodes.addAll(table.nodes);

    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableElement() => JS(
      'returns:TableElement;creates:TableElement;new:true',
      '#.createElement(#)',
      document,
      "table");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableElement.created() : super.created();

  TableCaptionElement caption;

  @JSName('rows')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @JSName('tBodies')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _tBodies;

  TableSectionElement tFoot;

  TableSectionElement tHead;

  @JSName('createCaption')
  TableCaptionElement _createCaption() native;

  @JSName('createTFoot')
  TableSectionElement _createTFoot() native;

  @JSName('createTHead')
  TableSectionElement _createTHead() native;

  void deleteCaption() native;

  void deleteRow(int index) native;

  void deleteTFoot() native;

  void deleteTHead() native;

  @JSName('insertRow')
  TableRowElement _insertRow([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableRowElement")
class TableRowElement extends HtmlElement {
  List<TableCellElement> get cells =>
      new _WrappedList<TableCellElement>(_cells);

  TableCellElement addCell() {
    return insertCell(-1);
  }

  TableCellElement insertCell(int index) => _insertCell(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement()
        .createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer)
        .nodes
        .single;
    var row = section.nodes.single;
    fragment.nodes.addAll(row.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableRowElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableRowElement() => JS(
      'returns:TableRowElement;creates:TableRowElement;new:true',
      '#.createElement(#)',
      document,
      "tr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableRowElement.created() : super.created();

  @JSName('cells')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _cells;

  final int rowIndex;

  final int sectionRowIndex;

  void deleteCell(int index) native;

  @JSName('insertCell')
  HtmlElement _insertCell([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableSectionElement")
class TableSectionElement extends HtmlElement {
  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableRowElement insertRow(int index) => _insertRow(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement()
        .createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer)
        .nodes
        .single;
    fragment.nodes.addAll(section.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableSectionElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableSectionElement.created() : super.created();

  @JSName('rows')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  void deleteRow(int index) native;

  @JSName('insertRow')
  HtmlElement _insertRow([int index]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TaskAttributionTiming")
class TaskAttributionTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory TaskAttributionTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final String containerId;

  final String containerName;

  final String containerSrc;

  final String containerType;

  @JSName('scriptURL')
  final String scriptUrl;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("HTMLTemplateElement")
class TemplateElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TemplateElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TemplateElement() => document.createElement("template");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TemplateElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('template');

  final DocumentFragment content;

  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);

    content.append(fragment);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("Text")
class Text extends CharacterData {
  factory Text(String data) => JS(
      'returns:Text;depends:none;effects:none;new:true',
      '#.createTextNode(#)',
      document,
      data);
  // To suppress missing implicit constructor warnings.
  factory Text._() {
    throw new UnsupportedError("Not supported");
  }

  final SlotElement assignedSlot;

  final String wholeText;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  Text splitText(int offset) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTextAreaElement")
class TextAreaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TextAreaElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TextAreaElement() => JS(
      'returns:TextAreaElement;creates:TextAreaElement;new:true',
      '#.createElement(#)',
      document,
      "textarea");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TextAreaElement.created() : super.created();

  String autocapitalize;

  bool autofocus;

  int cols;

  String defaultValue;

  String dirName;

  bool disabled;

  final FormElement form;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  int maxLength;

  int minLength;

  String name;

  String placeholder;

  bool readOnly;

  bool required;

  int rows;

  String selectionDirection;

  int selectionEnd;

  int selectionStart;

  final int textLength;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  String wrap;

  bool checkValidity() native;

  bool reportValidity() native;

  void select() native;

  void setCustomValidity(String error) native;

  void setRangeText(String replacement,
      {int start, int end, String selectionMode}) native;

  void setSelectionRange(int start, int end, [String direction]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextDetector")
class TextDetector extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TextDetector._() {
    throw new UnsupportedError("Not supported");
  }

  factory TextDetector() {
    return TextDetector._create_1();
  }
  static TextDetector _create_1() => JS('TextDetector', 'new TextDetector()');

  Future<List<DetectedText>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<DetectedText>>(JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("TextEvent")
class TextEvent extends UIEvent {
  factory TextEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Window view,
      String data}) {
    if (view == null) {
      view = window;
    }
    TextEvent e = document._createEvent("TextEvent");
    e._initTextEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TextEvent._() {
    throw new UnsupportedError("Not supported");
  }

  final String data;

  @JSName('initTextEvent')
  void _initTextEvent(String type, bool bubbles, bool cancelable, Window view,
      String data) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextMetrics")
class TextMetrics extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() {
    throw new UnsupportedError("Not supported");
  }

  final num actualBoundingBoxAscent;

  final num actualBoundingBoxDescent;

  final num actualBoundingBoxLeft;

  final num actualBoundingBoxRight;

  final num alphabeticBaseline;

  final num emHeightAscent;

  final num emHeightDescent;

  final num fontBoundingBoxAscent;

  final num fontBoundingBoxDescent;

  final num hangingBaseline;

  final num ideographicBaseline;

  final num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrack")
class TextTrack extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory TextTrack._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `cuechange` events to event
   * handlers that are not necessarily instances of [TextTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> cueChangeEvent =
      const EventStreamProvider<Event>('cuechange');

  final TextTrackCueList activeCues;

  final TextTrackCueList cues;

  final String id;

  final String kind;

  final String label;

  final String language;

  String mode;

  void addCue(TextTrackCue cue) native;

  void removeCue(TextTrackCue cue) native;

  /// Stream of `cuechange` events handled by this [TextTrack].
  Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrackCue")
class TextTrackCue extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCue._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `enter` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> enterEvent =
      const EventStreamProvider<Event>('enter');

  /**
   * Static factory designed to expose `exit` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> exitEvent =
      const EventStreamProvider<Event>('exit');

  num endTime;

  String id;

  bool pauseOnExit;

  num startTime;

  final TextTrack track;

  /// Stream of `enter` events handled by this [TextTrackCue].
  Stream<Event> get onEnter => enterEvent.forTarget(this);

  /// Stream of `exit` events handled by this [TextTrackCue].
  Stream<Event> get onExit => exitEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrackCueList")
class TextTrackCueList extends Interceptor
    with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue>
    implements List<TextTrackCue>, JavaScriptIndexingBehavior<TextTrackCue> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  TextTrackCue operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("TextTrackCue", "#[#]", this, index);
  }

  void operator []=(int index, TextTrackCue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrackCue> mixins.
  // TextTrackCue is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrackCue get first {
    if (this.length > 0) {
      return JS('TextTrackCue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrackCue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrackCue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrackCue elementAt(int index) => this[index];
  // -- end List<TextTrackCue> mixins.

  TextTrackCue __getter__(int index) native;

  TextTrackCue getCueById(String id) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrackList")
class TextTrackList extends EventTarget
    with ListMixin<TextTrack>, ImmutableListMixin<TextTrack>
    implements List<TextTrack>, JavaScriptIndexingBehavior<TextTrack> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackList._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [TextTrackList].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TrackEvent> addTrackEvent =
      const EventStreamProvider<TrackEvent>('addtrack');

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  int get length => JS("int", "#.length", this);

  TextTrack operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("TextTrack", "#[#]", this, index);
  }

  void operator []=(int index, TextTrack value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrack> mixins.
  // TextTrack is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrack get first {
    if (this.length > 0) {
      return JS('TextTrack', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrack get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrack', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrack get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrack', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrack elementAt(int index) => this[index];
  // -- end List<TextTrack> mixins.

  TextTrack __getter__(int index) native;

  TextTrack getTrackById(String id) native;

  /// Stream of `addtrack` events handled by this [TextTrackList].
  Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTimeElement")
class TimeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TimeElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TimeElement.created() : super.created();

  String dateTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("TimeRanges")
class TimeRanges extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TimeRanges._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  double end(int index) native;

  double start(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void TimeoutHandler();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTitleElement")
class TitleElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TitleElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TitleElement() => JS(
      'returns:TitleElement;creates:TitleElement;new:true',
      '#.createElement(#)',
      document,
      "title");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TitleElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Touch")
class Touch extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Touch._() {
    throw new UnsupportedError("Not supported");
  }

  factory Touch(Map initDict) {
    var initDict_1 = convertDartToNative_Dictionary(initDict);
    return Touch._create_1(initDict_1);
  }
  static Touch _create_1(initDict) => JS('Touch', 'new Touch(#)', initDict);

  @JSName('clientX')
  final num _clientX;

  @JSName('clientY')
  final num _clientY;

  final num force;

  final int identifier;

  @JSName('pageX')
  final num _pageX;

  @JSName('pageY')
  final num _pageY;

  @JSName('radiusX')
  final num _radiusX;

  @JSName('radiusY')
  final num _radiusY;

  final String region;

  final num rotationAngle;

  @JSName('screenX')
  final num _screenX;

  @JSName('screenY')
  final num _screenY;

  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @Creates('Element|Document')
  @Returns('Element|Document')
  final dynamic _get_target;

// As of Chrome 37, these all changed from long to double.  This code
// preserves backwards compatibility for the time being.
  int get __clientX => JS('num', '#.clientX', this).round();
  int get __clientY => JS('num', '#.clientY', this).round();
  int get __screenX => JS('num', '#.screenX', this).round();
  int get __screenY => JS('num', '#.screenY', this).round();
  int get __pageX => JS('num', '#.pageX', this).round();
  int get __pageY => JS('num', '#.pageY', this).round();
  int get __radiusX => JS('num', '#.radiusX', this).round();
  int get __radiusY => JS('num', '#.radiusY', this).round();

  Point get client => new Point(__clientX, __clientY);

  Point get page => new Point(__pageX, __pageY);

  Point get screen => new Point(__screenX, __screenY);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int get radiusX => __radiusX;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int get radiusY => __radiusY;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("TouchEvent")
class TouchEvent extends UIEvent {
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory TouchEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TouchEvent._create_1(type, eventInitDict_1);
    }
    return TouchEvent._create_2(type);
  }
  static TouchEvent _create_1(type, eventInitDict) =>
      JS('TouchEvent', 'new TouchEvent(#,#)', type, eventInitDict);
  static TouchEvent _create_2(type) =>
      JS('TouchEvent', 'new TouchEvent(#)', type);

  final bool altKey;

  final TouchList changedTouches;

  final bool ctrlKey;

  final bool metaKey;

  final bool shiftKey;

  final TouchList targetTouches;

  final TouchList touches;

  /**
   * Checks if touch events supported on the current platform.
   *
   * Note that touch events are only supported if the user is using a touch
   * device.
   */
  static bool get supported => Device.isEventTypeSupported('TouchEvent');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("TouchList")
class TouchList extends Interceptor
    with ListMixin<Touch>, ImmutableListMixin<Touch>
    implements JavaScriptIndexingBehavior<Touch>, List<Touch> {
  /// NB: This constructor likely does not work as you might expect it to! This
  /// constructor will simply fail (returning null) if you are not on a device
  /// with touch enabled. See dartbug.com/8314.
  // TODO(5760): createTouchList now uses varargs.
  factory TouchList() => null; //document._createTouchList();
  // To suppress missing implicit constructor warnings.
  factory TouchList._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!document.createTouchList');

  int get length => JS("int", "#.length", this);

  Touch operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Touch", "#[#]", this, index);
  }

  void operator []=(int index, Touch value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Touch> mixins.
  // Touch is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Touch get first {
    if (this.length > 0) {
      return JS('Touch', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Touch get last {
    int len = this.length;
    if (len > 0) {
      return JS('Touch', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Touch get single {
    int len = this.length;
    if (len == 1) {
      return JS('Touch', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Touch elementAt(int index) => this[index];
  // -- end List<Touch> mixins.

  Touch item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrackDefault")
class TrackDefault extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrackDefault._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackDefault(
      String type, String language, String label, List<String> kinds,
      [String byteStreamTrackID]) {
    if (byteStreamTrackID != null) {
      List kinds_1 = convertDartToNative_StringArray(kinds);
      return TrackDefault._create_1(
          type, language, label, kinds_1, byteStreamTrackID);
    }
    List kinds_1 = convertDartToNative_StringArray(kinds);
    return TrackDefault._create_2(type, language, label, kinds_1);
  }
  static TrackDefault _create_1(
          type, language, label, kinds, byteStreamTrackID) =>
      JS('TrackDefault', 'new TrackDefault(#,#,#,#,#)', type, language, label,
          kinds, byteStreamTrackID);
  static TrackDefault _create_2(type, language, label, kinds) => JS(
      'TrackDefault',
      'new TrackDefault(#,#,#,#)',
      type,
      language,
      label,
      kinds);

  final String byteStreamTrackID;

  final Object kinds;

  final String label;

  final String language;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrackDefaultList")
class TrackDefaultList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrackDefaultList._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackDefaultList([List<TrackDefault> trackDefaults]) {
    if (trackDefaults != null) {
      return TrackDefaultList._create_1(trackDefaults);
    }
    return TrackDefaultList._create_2();
  }
  static TrackDefaultList _create_1(trackDefaults) =>
      JS('TrackDefaultList', 'new TrackDefaultList(#)', trackDefaults);
  static TrackDefaultList _create_2() =>
      JS('TrackDefaultList', 'new TrackDefaultList()');

  final int length;

  TrackDefault item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLTrackElement")
class TrackElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TrackElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackElement() => document.createElement("track");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TrackElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('track');

  static const int ERROR = 3;

  static const int LOADED = 2;

  static const int LOADING = 1;

  static const int NONE = 0;

  @JSName('default')
  bool defaultValue;

  String kind;

  String label;

  final int readyState;

  String src;

  String srclang;

  final TextTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("TrackEvent")
class TrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory TrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TrackEvent._create_1(type, eventInitDict_1);
    }
    return TrackEvent._create_2(type);
  }
  static TrackEvent _create_1(type, eventInitDict) =>
      JS('TrackEvent', 'new TrackEvent(#,#)', type, eventInitDict);
  static TrackEvent _create_2(type) =>
      JS('TrackEvent', 'new TrackEvent(#)', type);

  @Creates('Null')
  final Object track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TransitionEvent,WebKitTransitionEvent")
class TransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory TransitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory TransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TransitionEvent._create_1(type, eventInitDict_1);
    }
    return TransitionEvent._create_2(type);
  }
  static TransitionEvent _create_1(type, eventInitDict) =>
      JS('TransitionEvent', 'new TransitionEvent(#,#)', type, eventInitDict);
  static TransitionEvent _create_2(type) =>
      JS('TransitionEvent', 'new TransitionEvent(#)', type);

  final num elapsedTime;

  final String propertyName;

  final String pseudoElement;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("TreeWalker")
class TreeWalker extends Interceptor {
  factory TreeWalker(Node root, int whatToShow) {
    return document._createTreeWalker(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory TreeWalker._() {
    throw new UnsupportedError("Not supported");
  }

  Node currentNode;

  final NodeFilter filter;

  final Node root;

  final int whatToShow;

  Node firstChild() native;

  Node lastChild() native;

  Node nextNode() native;

  Node nextSibling() native;

  Node parentNode() native;

  Node previousNode() native;

  Node previousSibling() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrustedHTML")
class TrustedHtml extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrustedHtml._() {
    throw new UnsupportedError("Not supported");
  }

  static TrustedHtml escape(String html) native;

  static TrustedHtml unsafelyCreate(String html) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrustedScriptURL")
class TrustedScriptUrl extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrustedScriptUrl._() {
    throw new UnsupportedError("Not supported");
  }

  static TrustedScriptUrl unsafelyCreate(String url) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrustedURL")
class TrustedUrl extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrustedUrl._() {
    throw new UnsupportedError("Not supported");
  }

  static TrustedUrl create(String url) native;

  static TrustedUrl unsafelyCreate(String url) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("UIEvent")
class UIEvent extends Event {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view,
      int detail: 0,
      bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    UIEvent e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }

  factory UIEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return UIEvent._create_1(type, eventInitDict_1);
    }
    return UIEvent._create_2(type);
  }
  static UIEvent _create_1(type, eventInitDict) =>
      JS('UIEvent', 'new UIEvent(#,#)', type, eventInitDict);
  static UIEvent _create_2(type) => JS('UIEvent', 'new UIEvent(#)', type);

  final int detail;

  final InputDeviceCapabilities sourceCapabilities;

  WindowBase get view => _convertNativeToDart_Window(this._get_view);
  @JSName('view')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_view;

  @JSName('which')
  @Unstable()
  final int _which;

  @JSName('initUIEvent')
  void _initUIEvent(String type, bool bubbles, bool cancelable, Window view,
      int detail) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLUListElement")
class UListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory UListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory UListElement() => JS(
      'returns:UListElement;creates:UListElement;new:true',
      '#.createElement(#)',
      document,
      "ul");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("UnderlyingSourceBase")
class UnderlyingSourceBase extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UnderlyingSourceBase._() {
    throw new UnsupportedError("Not supported");
  }

  Future cancel(Object reason) =>
      promiseToFuture(JS("", "#.cancel(#)", this, reason));

  void notifyLockAcquired() native;

  void notifyLockReleased() native;

  Future pull() => promiseToFuture(JS("", "#.pull()", this));

  Future start(Object stream) =>
      promiseToFuture(JS("", "#.start(#)", this, stream));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLUnknownElement")
class UnknownElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory UnknownElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UnknownElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("URL")
class Url extends Interceptor {
  static String createObjectUrl(blob_OR_source_OR_stream) => JS(
      'String',
      '(self.URL || self.webkitURL).createObjectURL(#)',
      blob_OR_source_OR_stream);

  static String createObjectUrlFromSource(MediaSource source) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', source);

  static String createObjectUrlFromStream(MediaStream stream) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', stream);

  static String createObjectUrlFromBlob(Blob blob) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', blob);

  static void revokeObjectUrl(String url) =>
      JS('void', '(self.URL || self.webkitURL).revokeObjectURL(#)', url);

  String toString() => JS('String', 'String(#)', this);

  // To suppress missing implicit constructor warnings.
  factory Url._() {
    throw new UnsupportedError("Not supported");
  }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  final UrlSearchParams searchParams;

  String username;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("URLSearchParams")
class UrlSearchParams extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlSearchParams._() {
    throw new UnsupportedError("Not supported");
  }

  factory UrlSearchParams([Object init]) {
    if (init != null) {
      return UrlSearchParams._create_1(init);
    }
    return UrlSearchParams._create_2();
  }
  static UrlSearchParams _create_1(init) =>
      JS('UrlSearchParams', 'new URLSearchParams(#)', init);
  static UrlSearchParams _create_2() =>
      JS('UrlSearchParams', 'new URLSearchParams()');

  void append(String name, String value) native;

  void delete(String name) native;

  String get(String name) native;

  List<String> getAll(String name) native;

  bool has(String name) native;

  void set(String name, String value) native;

  void sort() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class UrlUtilsReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtilsReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final String hash;

  final String host;

  final String hostname;

  final String href;

  final String origin;

  final String pathname;

  final String port;

  final String protocol;

  final String search;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VR")
class VR extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VR._() {
    throw new UnsupportedError("Not supported");
  }

  Future getDevices() => promiseToFuture(JS("", "#.getDevices()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRCoordinateSystem")
class VRCoordinateSystem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRCoordinateSystem._() {
    throw new UnsupportedError("Not supported");
  }

  Float32List getTransformTo(VRCoordinateSystem other) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDevice")
class VRDevice extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRDevice._() {
    throw new UnsupportedError("Not supported");
  }

  final String deviceName;

  final bool isExternal;

  Future requestSession([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.requestSession(#)", this, options_dict));
  }

  Future supportsSession([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.supportsSession(#)", this, options_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDeviceEvent")
class VRDeviceEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory VRDeviceEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRDeviceEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return VRDeviceEvent._create_1(type, eventInitDict_1);
  }
  static VRDeviceEvent _create_1(type, eventInitDict) =>
      JS('VRDeviceEvent', 'new VRDeviceEvent(#,#)', type, eventInitDict);

  final VRDevice device;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDisplay")
class VRDisplay extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRDisplay._() {
    throw new UnsupportedError("Not supported");
  }

  final VRDisplayCapabilities capabilities;

  num depthFar;

  num depthNear;

  final int displayId;

  final String displayName;

  final bool isPresenting;

  final VRStageParameters stageParameters;

  void cancelAnimationFrame(int handle) native;

  Future exitPresent() => promiseToFuture(JS("", "#.exitPresent()", this));

  VREyeParameters getEyeParameters(String whichEye) native;

  bool getFrameData(VRFrameData frameData) native;

  List<Map> getLayers() native;

  int requestAnimationFrame(FrameRequestCallback callback) native;

  Future requestPresent(List<Map> layers) =>
      promiseToFuture(JS("", "#.requestPresent(#)", this, layers));

  void submitFrame() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDisplayCapabilities")
class VRDisplayCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRDisplayCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  final bool canPresent;

  final bool hasExternalDisplay;

  final bool hasPosition;

  final int maxLayers;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDisplayEvent")
class VRDisplayEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory VRDisplayEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRDisplayEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return VRDisplayEvent._create_1(type, eventInitDict_1);
    }
    return VRDisplayEvent._create_2(type);
  }
  static VRDisplayEvent _create_1(type, eventInitDict) =>
      JS('VRDisplayEvent', 'new VRDisplayEvent(#,#)', type, eventInitDict);
  static VRDisplayEvent _create_2(type) =>
      JS('VRDisplayEvent', 'new VRDisplayEvent(#)', type);

  final VRDisplay display;

  final String reason;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VREyeParameters")
class VREyeParameters extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VREyeParameters._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List offset;

  final int renderHeight;

  final int renderWidth;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRFrameData")
class VRFrameData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRFrameData._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRFrameData() {
    return VRFrameData._create_1();
  }
  static VRFrameData _create_1() => JS('VRFrameData', 'new VRFrameData()');

  final Float32List leftProjectionMatrix;

  final Float32List leftViewMatrix;

  final VRPose pose;

  final Float32List rightProjectionMatrix;

  final Float32List rightViewMatrix;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRFrameOfReference")
class VRFrameOfReference extends VRCoordinateSystem {
  // To suppress missing implicit constructor warnings.
  factory VRFrameOfReference._() {
    throw new UnsupportedError("Not supported");
  }

  final VRStageBounds bounds;

  final num emulatedHeight;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRPose")
class VRPose extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRPose._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List angularAcceleration;

  final Float32List angularVelocity;

  final Float32List linearAcceleration;

  final Float32List linearVelocity;

  final Float32List orientation;

  final Float32List position;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRSession")
class VRSession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRSession._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  num depthFar;

  num depthNear;

  final VRDevice device;

  final bool exclusive;

  Future end() => promiseToFuture(JS("", "#.end()", this));

  Future requestFrameOfReference(String type, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.requestFrameOfReference(#, #)", this, type, options_dict));
  }

  Stream<Event> get onBlur => blurEvent.forTarget(this);

  Stream<Event> get onFocus => focusEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRSessionEvent")
class VRSessionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory VRSessionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRSessionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return VRSessionEvent._create_1(type, eventInitDict_1);
  }
  static VRSessionEvent _create_1(type, eventInitDict) =>
      JS('VRSessionEvent', 'new VRSessionEvent(#,#)', type, eventInitDict);

  final VRSession session;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRStageBounds")
class VRStageBounds extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRStageBounds._() {
    throw new UnsupportedError("Not supported");
  }

  final List<VRStageBoundsPoint> geometry;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRStageBoundsPoint")
class VRStageBoundsPoint extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRStageBoundsPoint._() {
    throw new UnsupportedError("Not supported");
  }

  final num x;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRStageParameters")
class VRStageParameters extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRStageParameters._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List sittingToStandingTransform;

  final num sizeX;

  final num sizeZ;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ValidityState")
class ValidityState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() {
    throw new UnsupportedError("Not supported");
  }

  final bool badInput;

  final bool customError;

  final bool patternMismatch;

  final bool rangeOverflow;

  final bool rangeUnderflow;

  final bool stepMismatch;

  final bool tooLong;

  final bool tooShort;

  final bool typeMismatch;

  final bool valid;

  final bool valueMissing;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLVideoElement")
class VideoElement extends MediaElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory VideoElement() => JS(
      'returns:VideoElement;creates:VideoElement;new:true',
      '#.createElement(#)',
      document,
      "video");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  VideoElement.created() : super.created();

  int height;

  String poster;

  final int videoHeight;

  final int videoWidth;

  @JSName('webkitDecodedFrameCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int decodedFrameCount;

  @JSName('webkitDroppedFrameCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int droppedFrameCount;

  int width;

  VideoPlaybackQuality getVideoPlaybackQuality() native;

  @JSName('webkitEnterFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void enterFullscreen() native;

  @JSName('webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void exitFullscreen() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VideoPlaybackQuality")
class VideoPlaybackQuality extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() {
    throw new UnsupportedError("Not supported");
  }

  final int corruptedVideoFrames;

  final num creationTime;

  final int droppedVideoFrames;

  final int totalVideoFrames;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VideoTrack")
class VideoTrack extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VideoTrack._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final String kind;

  final String label;

  final String language;

  bool selected;

  final SourceBuffer sourceBuffer;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VideoTrackList")
class VideoTrackList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VideoTrackList._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final int length;

  final int selectedIndex;

  VideoTrack __getter__(int index) native;

  VideoTrack getTrackById(String id) native;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VisualViewport")
class VisualViewport extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VisualViewport._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  final num height;

  final num offsetLeft;

  final num offsetTop;

  final num pageLeft;

  final num pageTop;

  final num scale;

  final num width;

  Stream<Event> get onResize => resizeEvent.forTarget(this);

  Stream<Event> get onScroll => scrollEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void VoidCallback();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VTTCue")
class VttCue extends TextTrackCue {
  // To suppress missing implicit constructor warnings.
  factory VttCue._() {
    throw new UnsupportedError("Not supported");
  }

  factory VttCue(num startTime, num endTime, String text) {
    return VttCue._create_1(startTime, endTime, text);
  }
  static VttCue _create_1(startTime, endTime, text) =>
      JS('VttCue', 'new VTTCue(#,#,#)', startTime, endTime, text);

  String align;

  @Creates('Null')
  @Returns('num|String')
  Object line;

  @Creates('Null')
  @Returns('num|String')
  Object position;

  VttRegion region;

  num size;

  bool snapToLines;

  String text;

  String vertical;

  @JSName('getCueAsHTML')
  DocumentFragment getCueAsHtml() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VTTRegion")
class VttRegion extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VttRegion._() {
    throw new UnsupportedError("Not supported");
  }

  factory VttRegion() {
    return VttRegion._create_1();
  }
  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');

  String id;

  int lines;

  num regionAnchorX;

  num regionAnchorY;

  String scroll;

  num viewportAnchorX;

  num viewportAnchorY;

  num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Use the WebSocket interface to connect to a WebSocket,
 * and to send and receive data on that WebSocket.
 *
 * To use a WebSocket in your web app, first create a WebSocket object,
 * passing the WebSocket URL as an argument to the constructor.
 *
 *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
 *
 * To send data on the WebSocket, use the [send] method.
 *
 *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
 *       webSocket.send(data);
 *     } else {
 *       print('WebSocket not connected, message $data not sent');
 *     }
 *
 * To receive data on the WebSocket, register a listener for message events.
 *
 *     webSocket.onMessage.listen((MessageEvent e) {
 *       receivedData(e.data);
 *     });
 *
 * The message event handler receives a [MessageEvent] object
 * as its sole argument.
 * You can also define open, close, and error handlers,
 * as specified by [WebSocketEvents].
 *
 * For more information, see the
 * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
 * section of the library tour and
 * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
 * an HTML5Rocks.com tutorial.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("WebSocket")
class WebSocket extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WebSocket._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<CloseEvent> closeEvent =
      const EventStreamProvider<CloseEvent>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  factory WebSocket(String url, [Object protocols]) {
    if (protocols != null) {
      return WebSocket._create_1(url, protocols);
    }
    return WebSocket._create_2(url);
  }
  static WebSocket _create_1(url, protocols) =>
      JS('WebSocket', 'new WebSocket(#,#)', url, protocols);
  static WebSocket _create_2(url) => JS('WebSocket', 'new WebSocket(#)', url);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', 'typeof window.WebSocket != "undefined"');

  static const int CLOSED = 3;

  static const int CLOSING = 2;

  static const int CONNECTING = 0;

  static const int OPEN = 1;

  String binaryType;

  final int bufferedAmount;

  final String extensions;

  final String protocol;

  final int readyState;

  final String url;

  void close([int code, String reason]) native;

  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void send(data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendBlob(Blob data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendString(String data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [WebSocket].
  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [WebSocket].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [WebSocket].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [WebSocket].
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WheelEvent")
class WheelEvent extends MouseEvent {
  factory WheelEvent(String type,
      {Window view,
      num deltaX: 0,
      num deltaY: 0,
      num deltaZ: 0,
      int deltaMode: 0,
      int detail: 0,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      int button: 0,
      bool canBubble: true,
      bool cancelable: true,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget relatedTarget}) {
    var options = {
      'view': view,
      'deltaMode': deltaMode,
      'deltaX': deltaX,
      'deltaY': deltaY,
      'deltaZ': deltaZ,
      'detail': detail,
      'screenX': screenX,
      'screenY': screenY,
      'clientX': clientX,
      'clientY': clientY,
      'button': button,
      'bubbles': canBubble,
      'cancelable': cancelable,
      'ctrlKey': ctrlKey,
      'altKey': altKey,
      'shiftKey': shiftKey,
      'metaKey': metaKey,
      'relatedTarget': relatedTarget,
    };

    if (view == null) {
      view = window;
    }

    return JS('WheelEvent', 'new WheelEvent(#, #)', type,
        convertDartToNative_Dictionary(options));
  }

  factory WheelEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return WheelEvent._create_1(type, eventInitDict_1);
    }
    return WheelEvent._create_2(type);
  }
  static WheelEvent _create_1(type, eventInitDict) =>
      JS('WheelEvent', 'new WheelEvent(#,#)', type, eventInitDict);
  static WheelEvent _create_2(type) =>
      JS('WheelEvent', 'new WheelEvent(#)', type);

  static const int DOM_DELTA_LINE = 0x01;

  static const int DOM_DELTA_PAGE = 0x02;

  static const int DOM_DELTA_PIXEL = 0x00;

  @JSName('deltaX')
  final num _deltaX;

  @JSName('deltaY')
  final num _deltaY;

  final num deltaZ;

  /**
   * The amount that is expected to scroll vertically, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaY](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY) from the W3C.
   */
  num get deltaY {
    if (JS('bool', '#.deltaY !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaY;
    }
    throw new UnsupportedError('deltaY is not supported');
  }

  /**
   * The amount that is expected to scroll horizontally, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaX](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaX) from the W3C.
   */
  num get deltaX {
    if (JS('bool', '#.deltaX !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaX;
    }
    throw new UnsupportedError('deltaX is not supported');
  }

  int get deltaMode {
    if (JS('bool', '!!(#.deltaMode)', this)) {
      return JS('int', '#.deltaMode', this);
    }
    // If not available then we're poly-filling and doing pixel scroll.
    return 0;
  }

  num get _wheelDelta => JS('num', '#.wheelDelta', this);
  num get _wheelDeltaX => JS('num', '#.wheelDeltaX', this);
  num get _detail => JS('num', '#.detail', this);

  bool get _hasInitMouseScrollEvent =>
      JS('bool', '!!(#.initMouseScrollEvent)', this);

  @JSName('initMouseScrollEvent')
  void _initMouseScrollEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget,
      int axis) native;

  bool get _hasInitWheelEvent => JS('bool', '!!(#.initWheelEvent)', this);
  @JSName('initWheelEvent')
  void _initWheelEvent(
      String eventType,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      int button,
      EventTarget relatedTarget,
      String modifiersList,
      int deltaX,
      int deltaY,
      int deltaZ,
      int deltaMode) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Top-level container for the current browser tab or window.
 *
 * In a web browser, each window has a [Window] object, but within the context
 * of a script, this object represents only the current window.
 * Each other window, tab, and iframe has its own [Window] object.
 *
 * Each window contains a [Document] object, which contains all of the window's
 * content.
 *
 * Use the top-level `window` object to access the current window.
 * For example:
 *
 *     // Draw a scene when the window repaints.
 *     drawScene(num delta) {...}
 *     window.animationFrame.then(drawScene);.
 *
 *     // Write to the console.
 *     window.console.log('Jinkies!');
 *     window.console.error('Jeepers!');
 *
 * **Note:** This class represents only the current window, while [WindowBase]
 * is a representation of any window, including other tabs, windows, and frames.
 *
 * ## See also
 *
 * * [WindowBase]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
@Native("Window,DOMWindow")
class Window extends EventTarget
    implements
        WindowEventHandlers,
        WindowBase,
        GlobalEventHandlers,
        _WindowTimers,
        WindowBase64 {
  /**
   * Returns a Future that completes just before the window is about to
   * repaint so the user can draw an animation frame.
   *
   * If you need to later cancel this animation, use [requestAnimationFrame]
   * instead.
   *
   * The [Future] completes to a timestamp that represents a floating
   * point value of the number of milliseconds that have elapsed since the page
   * started to load (which is also the timestamp at this call to
   * animationFrame).
   *
   * Note: The code that runs when the future completes should call
   * [animationFrame] again for the animation to continue.
   */
  Future<num> get animationFrame {
    var completer = new Completer<num>.sync();
    requestAnimationFrame((time) {
      completer.complete(time);
    });
    return completer.future;
  }

  /**
   * The newest document in this window.
   *
   * ## Other resources
   *
   * * [Loading web
   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
   *   from WHATWG.
   */
  Document get document => JS('Document', '#.document', this);

  WindowBase _open2(url, name) =>
      JS('Window|Null', '#.open(#,#)', this, url, name);

  WindowBase _open3(url, name, options) =>
      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);

  /**
   * Opens a new window.
   *
   * ## Other resources
   *
   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
   *   from MDN.
   */
  WindowBase open(String url, String name, [String options]) {
    if (options == null) {
      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
    } else {
      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
    }
  }

  // API level getter and setter for Location.
  // TODO: The cross domain safe wrapper can be inserted here.
  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  Location get location => _location;

  // TODO: consider forcing users to do: window.location.assign('string').
  /**
   * Sets the window's location, which causes the browser to navigate to the new
   * location. [value] may be a Location object or a String.
   */
  set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  set _location(value) {
    JS('void', '#.location = #', this, value);
  }

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  int requestAnimationFrame(FrameRequestCallback callback) {
    _ensureRequestAnimationFrame();
    return _requestAnimationFrame(_wrapZone(callback));
  }

  /**
   * Cancels an animation frame request.
   *
   * ## Other resources
   *
   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
   *   from MDN.
   */
  void cancelAnimationFrame(int id) {
    _ensureRequestAnimationFrame();
    _cancelAnimationFrame(id);
  }

  @JSName('requestAnimationFrame')
  int _requestAnimationFrame(FrameRequestCallback callback) native;

  @JSName('cancelAnimationFrame')
  void _cancelAnimationFrame(int id) native;

  _ensureRequestAnimationFrame() {
    if (JS('bool', '!!(#.requestAnimationFrame && #.cancelAnimationFrame)',
        this, this)) return;

    JS(
        'void',
        r"""
  (function($this) {
   var vendors = ['ms', 'moz', 'webkit', 'o'];
   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
     $this.cancelAnimationFrame =
         $this[vendors[i]+'CancelAnimationFrame'] ||
         $this[vendors[i]+'CancelRequestAnimationFrame'];
   }
   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
   $this.requestAnimationFrame = function(callback) {
      return window.setTimeout(function() {
        callback(Date.now());
      }, 16 /* 16ms ~= 60fps */);
   };
   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
  })(#)""",
        this);
  }

  /**
   * Gets an instance of the Indexed DB factory to being using Indexed DB.
   *
   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
   * current platform.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
  @SupportedBrowser(SupportedBrowser.IE, '10.0')
  IdbFactory get indexedDB => JS(
      'IdbFactory|Null', // If not supported, returns null.
      '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
      this,
      this,
      this);

  /// The debugging console for this window.
  Console get console => Console._safeConsole;

  /**
   * Access a sandboxed file system of `size` bytes.
   *
   * If `persistent` is true, the application will request permission from the
   * user to create lasting storage. This storage cannot be freed without the
   * user's permission. Returns a [Future] whose value stores a reference to
   * the sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent ? 1 : 0, size);
  }

  /**
   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
   * see http://dev.w3.org/csswg/cssom-view/#geometry
   */
  static bool get supportsPointConversions => DomPoint.supported;
  // To suppress missing implicit constructor warnings.
  factory Window._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `contentloaded` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> contentLoadedEvent =
      const EventStreamProvider<Event>('DOMContentLoaded');

  /**
   * Static factory designed to expose `devicemotion` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent =
      const EventStreamProvider<DeviceMotionEvent>('devicemotion');

  /**
   * Static factory designed to expose `deviceorientation` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<DeviceOrientationEvent>
      deviceOrientationEvent =
      const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  static const EventStreamProvider<Event> loadStartEvent =
      const EventStreamProvider<Event>('loadstart');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `pagehide` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> pageHideEvent =
      const EventStreamProvider<Event>('pagehide');

  /**
   * Static factory designed to expose `pageshow` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> pageShowEvent =
      const EventStreamProvider<Event>('pageshow');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  static const EventStreamProvider<Event> progressEvent =
      const EventStreamProvider<Event>('progress');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  /**
   * Static factory designed to expose `animationend` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<AnimationEvent> animationEndEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');

  /**
   * Static factory designed to expose `animationiteration` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<AnimationEvent> animationIterationEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');

  /**
   * Static factory designed to expose `animationstart` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<AnimationEvent> animationStartEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationStart');

  /**
   * Indicates that file system data cannot be cleared unless given user
   * permission.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
   *   from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  static const int PERSISTENT = 1;

  /**
   * Indicates that file system data can be cleared at any time.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  static const int TEMPORARY = 0;

  final _Worklet animationWorklet;

  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application
   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
   *   from HTML5Rocks.
   * * [Application cache
   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
   *   from WHATWG.
   */
  final ApplicationCache applicationCache;

  final _Worklet audioWorklet;

  final CacheStorage caches;

  final bool closed;

  final CookieStore cookieStore;

  /**
   * Entrypoint for the browser's cryptographic functions.
   *
   * ## Other resources
   *
   * * [Web cryptography API](http://www.w3.org/TR/WebCryptoAPI/) from W3C.
   */
  final Crypto crypto;

  final CustomElementRegistry customElements;

  /// *Deprecated*.
  String defaultStatus;

  /// *Deprecated*.
  String defaultstatus;

  /**
   * The ratio between physical pixels and logical CSS pixels.
   *
   * ## Other resources
   *
   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
   *   from quirksmode.
   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
   *   from quirksmode.
   */
  final num devicePixelRatio;

  final External external;

  /**
   * The current session history for this window's newest document.
   *
   * ## Other resources
   *
   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
   *   from WHATWG.
   */
  final History history;

  /**
   * The height of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [Window.innerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight)
   *   from MDN.
   */
  final int innerHeight;

  /**
   * The width of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [Window.innerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth)
   *   from MDN.
   */
  final int innerWidth;

  final bool isSecureContext;

  /**
   * Storage for this window that persists across sessions.
   *
   * ## Other resources
   *
   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
   *   from MDN.
   * * [The past, present & future of local storage for web
   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
   *   from W3C.
   */
  final Storage localStorage;

  /**
   * This window's location bar, which displays the URL.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp locationbar;

  /**
   * This window's menu bar, which displays menu commands.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp menubar;

  /**
   * The name of this window.
   *
   * ## Other resources
   *
   * * [Window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name)
   *   from MDN.
   */
  String name;

  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator
   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
   *   from WHATWG.
   */
  final Navigator navigator;

  /**
   * Whether objects are drawn offscreen before being displayed.
   *
   * ## Other resources
   *
   * * [offscreenBuffering](https://webplatform.github.io/docs/dom/HTMLElement/offscreenBuffering/)
   *   from WebPlatform.org.
   */
  final bool offscreenBuffering;

  WindowBase get opener => _convertNativeToDart_Window(this._get_opener);
  @JSName('opener')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_opener;

  set opener(Window value) {
    JS("void", "#.opener = #", this, value);
  }

  final int orientation;

  final String origin;

  /**
   * The height of this window including all user interface elements.
   *
   * ## Other resources
   *
   * * [Window.outerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/outerHeight)
   *   from MDN.
   */
  final int outerHeight;

  /**
   * The width of the window including all user interface elements.
   *
   * ## Other resources
   *
   * * [Window.outerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/outerWidth)
   *   from MDN.
   */
  final int outerWidth;

  @JSName('pageXOffset')
  /**
   * The distance this window has been scrolled horizontally.
   *
   * This attribute is an alias for [scrollX].
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX and
   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  final num _pageXOffset;

  @JSName('pageYOffset')
  /**
   * The distance this window has been scrolled vertically.
   *
   * This attribute is an alias for [scrollY].
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY and
   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  final num _pageYOffset;

  WindowBase get parent => _convertNativeToDart_Window(this._get_parent);
  @JSName('parent')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_parent;

  /**
   * Timing and navigation data for this window.
   *
   * ## Other resources
   *
   * * [Measuring page load speed with navigation
   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
   *   from HTML5Rocks.
   * * [Navigation timing
   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE)
  final Performance performance;

  /**
   * Information about the screen displaying this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final Screen screen;

  /**
   * The distance from the left side of the screen to the left side of this
   * window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenLeft;

  /**
   * The distance from the top of the screen to the top of this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenTop;

  /**
   * The distance from the left side of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenX;

  /**
   * The distance from the top of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenY;

  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp scrollbars;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
   *   from MDN.
   */
  WindowBase get self => _convertNativeToDart_Window(this._get_self);
  @JSName('self')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
   *   from MDN.
   */
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_self;

  /**
   * Storage for this window that is cleared when this session ends.
   *
   * ## Other resources
   *
   * * [DOM storage
   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
   *   from MDN.
   * * [The past, present & future of local storage for web
   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage
   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
   */
  final Storage sessionStorage;

  /**
   * Access to speech synthesis in the browser.
   *
   * ## Other resources
   *
   * * [Web speech
   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
   *   from W3C.
   */
  final SpeechSynthesis speechSynthesis;

  /// *Deprecated*.
  String status;

  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp statusbar;

  /**
   * Access to CSS media queries.
   *
   * ## Other resources
   *
   * * [StyleMedia class
   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
   *   from Safari Developer Library.
   */
  final StyleMedia styleMedia;

  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp toolbar;

  WindowBase get top => _convertNativeToDart_Window(this._get_top);
  @JSName('top')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_top;

  final VisualViewport visualViewport;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
   *   from MDN.
   */
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('window')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
   *   from MDN.
   */
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_window;

  @Creates('Window|=Object')
  @Returns('Window|=Object')
  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int)) {
      return _convertNativeToDart_Window(__getter___1(index_OR_name));
    }
    if ((index_OR_name is String)) {
      return _convertNativeToDart_Window(__getter___2(index_OR_name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('__getter__')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___1(int index) native;
  @JSName('__getter__')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___2(String name) native;

  /**
   * Displays a modal alert to the user.
   *
   * ## Other resources
   *
   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
   *   from WHATWG.
   */
  void alert([String message]) native;

  void cancelIdleCallback(int handle) native;

  void close() native;

  /**
   * Displays a modal OK/Cancel prompt to the user.
   *
   * ## Other resources
   *
   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
   *   from WHATWG.
   */
  bool confirm([String message]) native;

  Future fetch(/*RequestInfo*/ input, [Map init]) {
    var init_dict = null;
    if (init != null) {
      init_dict = convertDartToNative_Dictionary(init);
    }
    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
  }

  /**
   * Finds text in this window.
   *
   * ## Other resources
   *
   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
   *   from MDN.
   */
  bool find(String string, bool caseSensitive, bool backwards, bool wrap,
      bool wholeWord, bool searchInFrames, bool showDialog) native;

  @JSName('getComputedStyle')
  CssStyleDeclaration _getComputedStyle(Element elt, [String pseudoElt]) native;

  StylePropertyMapReadonly getComputedStyleMap(
      Element element, String pseudoElement) native;

  @JSName('getMatchedCSSRules')
  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  List<CssRule> getMatchedCssRules(Element element, String pseudoElement)
      native;

  /**
   * Returns the currently selected text.
   *
   * ## Other resources
   *
   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
   *   from MDN.
   */
  Selection getSelection() native;

  /**
   * Returns a list of media queries for the given query string.
   *
   * ## Other resources
   *
   * * [Testing media
   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
   *   from MDN.
   * * [The MediaQueryList
   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
   */
  MediaQueryList matchMedia(String query) native;

  /**
   * Moves this window.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
   *   from MDN.
   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
   */
  void moveBy(int x, int y) native;

  @JSName('moveTo')
  void _moveTo(int x, int y) native;

  @JSName('openDatabase')

  /// *Deprecated.*
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates('SqlDatabase')
  SqlDatabase _openDatabase(
      String name, String version, String displayName, int estimatedSize,
      [DatabaseCallback creationCallback]) native;

  void postMessage(/*any*/ message, String targetOrigin,
      [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, targetOrigin, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1, targetOrigin);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, targetOrigin, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message, targetOrigin) native;

  /**
   * Opens the print dialog for this window.
   *
   * ## Other resources
   *
   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
   *   from MDN.
   */
  void print() native;

  int requestIdleCallback(IdleRequestCallback callback, [Map options]) {
    if (options != null) {
      var callback_1 = convertDartClosureToJS(callback, 1);
      var options_2 = convertDartToNative_Dictionary(options);
      return _requestIdleCallback_1(callback_1, options_2);
    }
    var callback_1 = convertDartClosureToJS(callback, 1);
    return _requestIdleCallback_2(callback_1);
  }

  @JSName('requestIdleCallback')
  int _requestIdleCallback_1(callback, options) native;
  @JSName('requestIdleCallback')
  int _requestIdleCallback_2(callback) native;

  /**
   * Resizes this window by an offset.
   *
   * ## Other resources
   *
   * * [Window.resizeBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeBy)
   *   from MDN.
   */
  void resizeBy(int x, int y) native;

  /**
   * Resizes this window to a specific width and height.
   *
   * ## Other resources
   *
   * * [Window.resizeTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeTo)
   *   from MDN.
   */
  void resizeTo(int x, int y) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void scroll([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scroll_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scroll_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scroll_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scroll_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void _scroll_1() native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void _scroll_2(options) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void _scroll_3(num x, num y) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void _scroll_4(int x, int y) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void _scroll_5(int x, int y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void scrollBy([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scrollBy_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollBy_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scrollBy_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scrollBy_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_1() native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_2(options) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_3(num x, num y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_4(int x, int y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_5(int x, int y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  void scrollTo([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scrollTo_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollTo_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scrollTo_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scrollTo_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  void _scrollTo_1() native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  void _scrollTo_2(options) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  void _scrollTo_3(num x, num y) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  void _scrollTo_4(int x, int y) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  void _scrollTo_5(int x, int y, scrollOptions) native;

  /**
   * Stops the window from loading.
   *
   * ## Other resources
   *
   * * [The Window
   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
   *   from W3C.
   */
  void stop() native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  void __requestFileSystem(
      int type, int size, _FileSystemCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  Future<FileSystem> _requestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    __requestFileSystem(type, size, (value) {
      applyExtension('DOMFileSystem', value);
      applyExtension('DirectoryEntry', value.root);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry
   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry
   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  Future<Entry> resolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _resolveLocalFileSystemUrl(url, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  // From WindowBase64

  String atob(String atob) native;

  String btoa(String btoa) native;

  // From WindowTimers

  @JSName('setInterval')
  int _setInterval_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('setTimeout')
  int _setTimeout_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('clearInterval')
  void _clearInterval([int handle]) native;

  @JSName('clearTimeout')
  void _clearTimeout([int handle]) native;

  @JSName('setInterval')
  int _setInterval(Object handler, [int timeout]) native;

  @JSName('setTimeout')
  int _setTimeout(Object handler, [int timeout]) native;

  /// Stream of `contentloaded` events handled by this [Window].
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

  /// Stream of `abort` events handled by this [Window].
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Window].
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  Stream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Window].
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Window].
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Window].
  Stream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Window].
  @DomName('Window.ondblclick')
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  Stream<DeviceMotionEvent> get onDeviceMotion =>
      deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  Stream<DeviceOrientationEvent> get onDeviceOrientation =>
      deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  Stream<Event> get onDurationChange =>
      Element.durationChangeEvent.forTarget(this);

  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Window].
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Window].
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `hashchange` events handled by this [Window].
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  /// Stream of `input` events handled by this [Window].
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  Stream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent.forTarget(this);

  Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `message` events handled by this [Window].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Window].
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  Stream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  Stream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  Stream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent.forTarget(this);

  /// Stream of `offline` events handled by this [Window].
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  /// Stream of `online` events handled by this [Window].
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  /// Stream of `pagehide` events handled by this [Window].
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  /// Stream of `popstate` events handled by this [Window].
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  Stream<Event> get onProgress => progressEvent.forTarget(this);

  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `storage` events handled by this [Window].
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Window].
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  Stream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  Stream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  Stream<TransitionEvent> get onTransitionEnd =>
      Element.transitionEndEvent.forTarget(this);

  /// Stream of `unload` events handled by this [Window].
  Stream<Event> get onUnload => unloadEvent.forTarget(this);

  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  Stream<AnimationEvent> get onAnimationEnd =>
      animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  Stream<AnimationEvent> get onAnimationIteration =>
      animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  Stream<AnimationEvent> get onAnimationStart =>
      animationStartEvent.forTarget(this);

  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /// Stream of `wheel` events handled by this [Window].
  Stream<WheelEvent> get onWheel => Element.wheelEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
   *   from MDN.
   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
   *   from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

  @JSName('openDatabase')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates('SqlDatabase')
  SqlDatabase openDatabase(
      String name, String version, String displayName, int estimatedSize,
      [DatabaseCallback creationCallback]) {
    var db;
    if (creationCallback == null)
      db = _openDatabase(name, version, displayName, estimatedSize);
    else
      db = _openDatabase(
          name, version, displayName, estimatedSize, creationCallback);

    applyExtension('Database', db);

    return db;
  }

  int get pageXOffset => JS('num', '#.pageXOffset', this).round();

  int get pageYOffset => JS('num', '#.pageYOffset', this).round();

  /**
   * The distance this window has been scrolled horizontally.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  int get scrollX => JS('bool', '("scrollX" in #)', this)
      ? JS('num', '#.scrollX', this).round()
      : document.documentElement.scrollLeft;

  /**
   * The distance this window has been scrolled vertically.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  int get scrollY => JS('bool', '("scrollY" in #)', this)
      ? JS('num', '#.scrollY', this).round()
      : document.documentElement.scrollTop;
}

class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base) : super(base);

  String get returnValue => _returnValue;

  set returnValue(String value) {
    _returnValue = value;
    // FF and IE use the value as the return value, Chrome will return this from
    // the event callback function.
    if (JS('bool', '("returnValue" in #)', wrapped)) {
      JS('void', '#.returnValue = #', wrapped, value);
    }
  }
}

class _BeforeUnloadEventStreamProvider
    implements EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    // Specify the generic type for EventStream only in dart2js.
    var stream = new _EventStream<BeforeUnloadEvent>(e, _eventType, useCapture);
    var controller = new StreamController<BeforeUnloadEvent>(sync: true);

    stream.listen((event) {
      var wrapped = new _BeforeUnloadEvent(event);
      controller.add(wrapped);
    });

    return controller.stream;
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e,
      {bool useCapture: false}) {
    // Specify the generic type for _ElementEventStreamImpl only in dart2js.
    return new _ElementEventStreamImpl<BeforeUnloadEvent>(
        e, _eventType, useCapture);
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList<Element> e,
      {bool useCapture: false}) {
    // Specify the generic type for _ElementEventStreamImpl only in dart2js.
    return new _ElementListEventStreamImpl<BeforeUnloadEvent>(
        e, _eventType, useCapture);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class WindowBase64 extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WindowBase64._() {
    throw new UnsupportedError("Not supported");
  }

  String atob(String atob);

  String btoa(String btoa);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WindowClient")
class WindowClient extends Client {
  // To suppress missing implicit constructor warnings.
  factory WindowClient._() {
    throw new UnsupportedError("Not supported");
  }

  final bool focused;

  final String visibilityState;

  Future<WindowClient> focus() =>
      promiseToFuture<WindowClient>(JS("", "#.focus()", this));

  Future<WindowClient> navigate(String url) =>
      promiseToFuture<WindowClient>(JS("", "#.navigate(#)", this, url));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class WindowEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WindowEventHandlers._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  Stream<Event> get onUnload => unloadEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("Worker")
class Worker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory Worker._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  factory Worker(String scriptUrl) {
    return Worker._create_1(scriptUrl);
  }
  static Worker _create_1(scriptUrl) =>
      JS('Worker', 'new Worker(#)', scriptUrl);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '(typeof window.Worker != "undefined")');

  void postMessage(/*any*/ message, [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message) native;

  void terminate() native;

  /// Stream of `error` events handled by this [Worker].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [Worker].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerGlobalScope")
class WorkerGlobalScope extends EventTarget
    implements _WindowTimers, WindowBase64 {
  // To suppress missing implicit constructor warnings.
  factory WorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  final String addressSpace;

  final CacheStorage caches;

  final Crypto crypto;

  final IdbFactory indexedDB;

  final bool isSecureContext;

  final _WorkerLocation location;

  final _WorkerNavigator navigator;

  final String origin;

  final WorkerPerformance performance;

  final WorkerGlobalScope self;

  Future fetch(/*RequestInfo*/ input, [Map init]) {
    var init_dict = null;
    if (init != null) {
      init_dict = convertDartToNative_Dictionary(init);
    }
    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
  }

  void importScripts(String urls) native;

  // From WindowBase64

  String atob(String atob) native;

  String btoa(String btoa) native;

  // From WindowTimers

  @JSName('setInterval')
  int _setInterval_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('setTimeout')
  int _setTimeout_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('clearInterval')
  void _clearInterval([int handle]) native;

  @JSName('clearTimeout')
  void _clearTimeout([int handle]) native;

  @JSName('setInterval')
  int _setInterval(Object handler, [int timeout]) native;

  @JSName('setTimeout')
  int _setTimeout(Object handler, [int timeout]) native;

  /// Stream of `error` events handled by this [WorkerGlobalScope].
  Stream<Event> get onError => errorEvent.forTarget(this);

  static WorkerGlobalScope get instance => _workerSelf;
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerPerformance")
class WorkerPerformance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() {
    throw new UnsupportedError("Not supported");
  }

  final MemoryInfo memory;

  final num timeOrigin;

  void clearMarks(String markName) native;

  void clearMeasures(String measureName) native;

  void clearResourceTimings() native;

  List<PerformanceEntry> getEntries() native;

  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  List<PerformanceEntry> getEntriesByType(String entryType) native;

  void mark(String markName) native;

  void measure(String measureName, String startMark, String endMark) native;

  double now() native;

  void setResourceTimingBufferSize(int maxSize) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkletAnimation")
class WorkletAnimation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WorkletAnimation._() {
    throw new UnsupportedError("Not supported");
  }

  factory WorkletAnimation(
      String animatorName,
      List<KeyframeEffectReadOnly> effects,
      List<Object> timelines,
      /*SerializedScriptValue*/ options) {
    var options_1 = convertDartToNative_SerializedScriptValue(options);
    return WorkletAnimation._create_1(
        animatorName, effects, timelines, options_1);
  }
  static WorkletAnimation _create_1(
          animatorName, effects, timelines, options) =>
      JS('WorkletAnimation', 'new WorkletAnimation(#,#,#,#)', animatorName,
          effects, timelines, options);

  final String playState;

  void cancel() native;

  void play() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkletGlobalScope")
class WorkletGlobalScope extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
@deprecated // experimental
@Native("XPathEvaluator")
class XPathEvaluator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathEvaluator._() {
    throw new UnsupportedError("Not supported");
  }

  factory XPathEvaluator() {
    return XPathEvaluator._create_1();
  }
  static XPathEvaluator _create_1() =>
      JS('XPathEvaluator', 'new XPathEvaluator()');

  XPathExpression createExpression(String expression, XPathNSResolver resolver)
      native;

  XPathNSResolver createNSResolver(Node nodeResolver) native;

  XPathResult evaluate(
      String expression, Node contextNode, XPathNSResolver resolver,
      [int type, Object inResult]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
@Native("XPathExpression")
class XPathExpression extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() {
    throw new UnsupportedError("Not supported");
  }

  XPathResult evaluate(Node contextNode, [int type, Object inResult]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
@Native("XPathNSResolver")
class XPathNSResolver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('lookupNamespaceURI')
  String lookupNamespaceUri(String prefix) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
@deprecated // experimental
@Native("XPathResult")
class XPathResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathResult._() {
    throw new UnsupportedError("Not supported");
  }

  static const int ANY_TYPE = 0;

  static const int ANY_UNORDERED_NODE_TYPE = 8;

  static const int BOOLEAN_TYPE = 3;

  static const int FIRST_ORDERED_NODE_TYPE = 9;

  static const int NUMBER_TYPE = 1;

  static const int ORDERED_NODE_ITERATOR_TYPE = 5;

  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;

  static const int STRING_TYPE = 2;

  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;

  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;

  final bool booleanValue;

  final bool invalidIteratorState;

  final num numberValue;

  final int resultType;

  final Node singleNodeValue;

  final int snapshotLength;

  final String stringValue;

  Node iterateNext() native;

  Node snapshotItem(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("XMLDocument")
class XmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory XmlDocument._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
@deprecated // stable
@Native("XMLSerializer")
class XmlSerializer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XmlSerializer._() {
    throw new UnsupportedError("Not supported");
  }

  factory XmlSerializer() {
    return XmlSerializer._create_1();
  }
  static XmlSerializer _create_1() =>
      JS('XmlSerializer', 'new XMLSerializer()');

  String serializeToString(Node root) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
@Native("XSLTProcessor")
class XsltProcessor extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XsltProcessor._() {
    throw new UnsupportedError("Not supported");
  }

  factory XsltProcessor() {
    return XsltProcessor._create_1();
  }
  static XsltProcessor _create_1() =>
      JS('XsltProcessor', 'new XSLTProcessor()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');

  void clearParameters() native;

  String getParameter(String namespaceURI, String localName) native;

  void importStylesheet(Node style) native;

  void removeParameter(String namespaceURI, String localName) native;

  void reset() native;

  void setParameter(String namespaceURI, String localName, String value) native;

  Document transformToDocument(Node source) native;

  DocumentFragment transformToFragment(Node source, Document output) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Attr")
class _Attr extends Node {
  // To suppress missing implicit constructor warnings.
  factory _Attr._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('localName')
  final String _localName;

  final String name;

  @JSName('namespaceURI')
  final String _namespaceUri;

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Bluetooth")
abstract class _Bluetooth extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Bluetooth._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothCharacteristicProperties")
abstract class _BluetoothCharacteristicProperties extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothCharacteristicProperties._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothDevice")
abstract class _BluetoothDevice extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothDevice._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTCharacteristic")
abstract class _BluetoothRemoteGATTCharacteristic extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTCharacteristic._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTServer")
abstract class _BluetoothRemoteGATTServer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTServer._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTService")
abstract class _BluetoothRemoteGATTService extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTService._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothUUID")
abstract class _BluetoothUUID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothUUID._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BudgetService")
class _BudgetService extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BudgetService._() {
    throw new UnsupportedError("Not supported");
  }

  Future<BudgetState> getBudget() =>
      promiseToFuture<BudgetState>(JS("", "#.getBudget()", this));

  Future<double> getCost(String operation) =>
      promiseToFuture<double>(JS("", "#.getCost(#)", this, operation));

  Future<bool> reserve(String operation) =>
      promiseToFuture<bool>(JS("", "#.reserve(#)", this, operation));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Cache")
abstract class _Cache extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Cache._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class _CanvasPath extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _CanvasPath._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Clipboard")
class _Clipboard extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _Clipboard._() {
    throw new UnsupportedError("Not supported");
  }

  Future<DataTransfer> read() =>
      promiseToFuture<DataTransfer>(JS("", "#.read()", this));

  Future<String> readText() =>
      promiseToFuture<String>(JS("", "#.readText()", this));

  Future write(DataTransfer data) =>
      promiseToFuture(JS("", "#.write(#)", this, data));

  Future writeText(String data) =>
      promiseToFuture(JS("", "#.writeText(#)", this, data));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSRuleList")
class _CssRuleList extends Interceptor
    with ListMixin<CssRule>, ImmutableListMixin<CssRule>
    implements JavaScriptIndexingBehavior<CssRule>, List<CssRule> {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  CssRule operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("CssRule", "#[#]", this, index);
  }

  void operator []=(int index, CssRule value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<CssRule> mixins.
  // CssRule is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  CssRule get first {
    if (this.length > 0) {
      return JS('CssRule', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  CssRule get last {
    int len = this.length;
    if (len > 0) {
      return JS('CssRule', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  CssRule get single {
    int len = this.length;
    if (len == 1) {
      return JS('CssRule', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  CssRule elementAt(int index) => this[index];
  // -- end List<CssRule> mixins.

  CssRule item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("DOMFileSystemSync")
abstract class _DOMFileSystemSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _DOMFileSystemSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryEntrySync")
abstract class _DirectoryEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryEntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryReaderSync")
abstract class _DirectoryReaderSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryReaderSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
@Native("DocumentType")
abstract class _DocumentType extends Node implements ChildNode {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() {
    throw new UnsupportedError("Not supported");
  }

  // From ChildNode

}

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ClientRect,DOMRect")
class _DomRect extends DomRectReadOnly implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight =>
      new Point(this.left + this.width, this.top + this.height);
  Point get bottomLeft => new Point(this.left, this.top + this.height);

  // To suppress missing implicit constructor warnings.
  factory _DomRect._() {
    throw new UnsupportedError("Not supported");
  }

  factory _DomRect([num x, num y, num width, num height]) {
    if (height != null) {
      return _DomRect._create_1(x, y, width, height);
    }
    if (width != null) {
      return _DomRect._create_2(x, y, width);
    }
    if (y != null) {
      return _DomRect._create_3(x, y);
    }
    if (x != null) {
      return _DomRect._create_4(x);
    }
    return _DomRect._create_5();
  }
  static _DomRect _create_1(x, y, width, height) =>
      JS('_DomRect', 'new DOMRect(#,#,#,#)', x, y, width, height);
  static _DomRect _create_2(x, y, width) =>
      JS('_DomRect', 'new DOMRect(#,#,#)', x, y, width);
  static _DomRect _create_3(x, y) => JS('_DomRect', 'new DOMRect(#,#)', x, y);
  static _DomRect _create_4(x) => JS('_DomRect', 'new DOMRect(#)', x);
  static _DomRect _create_5() => JS('_DomRect', 'new DOMRect()');

  // Shadowing definition.
  num get height => JS("num", "#.height", this);

  set height(num value) {
    JS("void", "#.height = #", this, value);
  }

  // Shadowing definition.
  num get width => JS("num", "#.width", this);

  set width(num value) {
    JS("void", "#.width = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }
}

/**
 * This is the [Jenkins hash function][1] but using masking to keep
 * values in SMI range.
 *
 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
 *
 * Use:
 * Hash each value with the hash of the previous value, then get the final
 * hash by calling finish.
 *
 *     var hash = 0;
 *     for (var value in values) {
 *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
 *     }
 *     hash = JenkinsSmiHash.finish(hash);
 */
class _JenkinsSmiHash {
  // TODO(11617): This class should be optimized and standardized elsewhere.

  static int combine(int hash, int value) {
    hash = 0x1fffffff & (hash + value);
    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
    return hash ^ (hash >> 6);
  }

  static int finish(int hash) {
    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
    hash = hash ^ (hash >> 11);
    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
  }

  static int hash2(a, b) => finish(combine(combine(0, a), b));

  static int hash4(a, b, c, d) =>
      finish(combine(combine(combine(combine(0, a), b), c), d));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("EntrySync")
abstract class _EntrySync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _EntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileEntrySync")
abstract class _FileEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _FileEntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileReaderSync")
abstract class _FileReaderSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _FileReaderSync._() {
    throw new UnsupportedError("Not supported");
  }

  factory _FileReaderSync() {
    return _FileReaderSync._create_1();
  }
  static _FileReaderSync _create_1() =>
      JS('_FileReaderSync', 'new FileReaderSync()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileWriterSync")
abstract class _FileWriterSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _FileWriterSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadList")
class _GamepadList extends Interceptor
    with ListMixin<Gamepad>, ImmutableListMixin<Gamepad>
    implements List<Gamepad>, JavaScriptIndexingBehavior<Gamepad> {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Gamepad operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Gamepad|Null", "#[#]", this, index);
  }

  void operator []=(int index, Gamepad value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Gamepad> mixins.
  // Gamepad is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Gamepad get first {
    if (this.length > 0) {
      return JS('Gamepad|Null', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Gamepad get last {
    int len = this.length;
    if (len > 0) {
      return JS('Gamepad|Null', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Gamepad get single {
    int len = this.length;
    if (len == 1) {
      return JS('Gamepad|Null', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Gamepad elementAt(int index) => this[index];
  // -- end List<Gamepad> mixins.

  Gamepad item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
@deprecated // deprecated
@Native("HTMLAllCollection")
abstract class _HTMLAllCollection extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('item')
  Element _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
@deprecated // deprecated
@Native("HTMLDirectoryElement")
abstract class _HTMLDirectoryElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLDirectoryElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLDirectoryElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
@deprecated // deprecated
@Native("HTMLFontElement")
abstract class _HTMLFontElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFontElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
@deprecated // deprecated
@Native("HTMLFrameElement")
abstract class _HTMLFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
@Native("HTMLFrameSetElement")
abstract class _HTMLFrameSetElement extends HtmlElement
    implements WindowEventHandlers {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameSetElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameSetElement.created() : super.created();
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
@Native("HTMLMarqueeElement")
abstract class _HTMLMarqueeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLMarqueeElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Mojo")
abstract class _Mojo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Mojo._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoHandle")
abstract class _MojoHandle extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _MojoHandle._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoInterfaceInterceptor")
abstract class _MojoInterfaceInterceptor extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _MojoInterfaceInterceptor._() {
    throw new UnsupportedError("Not supported");
  }

  factory _MojoInterfaceInterceptor(String interfaceName, [String scope]) {
    if (scope != null) {
      return _MojoInterfaceInterceptor._create_1(interfaceName, scope);
    }
    return _MojoInterfaceInterceptor._create_2(interfaceName);
  }
  static _MojoInterfaceInterceptor _create_1(interfaceName, scope) => JS(
      '_MojoInterfaceInterceptor',
      'new MojoInterfaceInterceptor(#,#)',
      interfaceName,
      scope);
  static _MojoInterfaceInterceptor _create_2(interfaceName) => JS(
      '_MojoInterfaceInterceptor',
      'new MojoInterfaceInterceptor(#)',
      interfaceName);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoInterfaceRequestEvent")
abstract class _MojoInterfaceRequestEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory _MojoInterfaceRequestEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory _MojoInterfaceRequestEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _MojoInterfaceRequestEvent._create_1(type, eventInitDict_1);
    }
    return _MojoInterfaceRequestEvent._create_2(type);
  }
  static _MojoInterfaceRequestEvent _create_1(type, eventInitDict) => JS(
      '_MojoInterfaceRequestEvent',
      'new MojoInterfaceRequestEvent(#,#)',
      type,
      eventInitDict);
  static _MojoInterfaceRequestEvent _create_2(type) => JS(
      '_MojoInterfaceRequestEvent', 'new MojoInterfaceRequestEvent(#)', type);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoWatcher")
abstract class _MojoWatcher extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _MojoWatcher._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NFC")
abstract class _NFC extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _NFC._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
@Native("NamedNodeMap,MozNamedAttrMap")
class _NamedNodeMap extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  _Attr getNamedItem(String name) native;

  _Attr getNamedItemNS(String namespaceURI, String localName) native;

  _Attr item(int index) native;

  _Attr removeNamedItem(String name) native;

  _Attr removeNamedItemNS(String namespaceURI, String localName) native;

  _Attr setNamedItem(_Attr attr) native;

  _Attr setNamedItemNS(_Attr attr) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@deprecated // nonstandard
@Native("PagePopupController")
abstract class _PagePopupController extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Omit RadioNodeList for dart2js.  The Dart Form and FieldSet APIs don't
// currently expose an API the returns RadioNodeList.  The only use of a
// RadioNodeList is to get the selected value and it will be cleaner to
// introduce a different API for that purpose.
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Report")
class _Report extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Report._() {
    throw new UnsupportedError("Not supported");
  }

  final ReportBody body;

  final String type;

  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Request")
class _Request extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Request._() {
    throw new UnsupportedError("Not supported");
  }

  factory _Request(Object input, [Map requestInitDict]) {
    if (requestInitDict != null) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _Request._create_1(input, requestInitDict_1);
    }
    return _Request._create_2(input);
  }
  static _Request _create_1(input, requestInitDict) =>
      JS('_Request', 'new Request(#,#)', input, requestInitDict);
  static _Request _create_2(input) => JS('_Request', 'new Request(#)', input);

  final String cache;

  final String credentials;

  final Headers headers;

  final String integrity;

  final String mode;

  final String redirect;

  final String referrer;

  final String referrerPolicy;

  final String url;

  _Request clone() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
@Native("ResourceProgressEvent")
abstract class _ResourceProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory _ResourceProgressEvent._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Response")
abstract class _Response extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Response._() {
    throw new UnsupportedError("Not supported");
  }

  factory _Response([Object body, Map init]) {
    if (init != null) {
      var init_1 = convertDartToNative_Dictionary(init);
      return _Response._create_1(body, init_1);
    }
    if (body != null) {
      return _Response._create_2(body);
    }
    return _Response._create_3();
  }
  static _Response _create_1(body, init) =>
      JS('_Response', 'new Response(#,#)', body, init);
  static _Response _create_2(body) => JS('_Response', 'new Response(#)', body);
  static _Response _create_3() => JS('_Response', 'new Response()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechRecognitionResultList")
class _SpeechRecognitionResultList extends Interceptor
    with
        ListMixin<SpeechRecognitionResult>,
        ImmutableListMixin<SpeechRecognitionResult>
    implements
        JavaScriptIndexingBehavior<SpeechRecognitionResult>,
        List<SpeechRecognitionResult> {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  SpeechRecognitionResult operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SpeechRecognitionResult", "#[#]", this, index);
  }

  void operator []=(int index, SpeechRecognitionResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechRecognitionResult> mixins.
  // SpeechRecognitionResult is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechRecognitionResult get first {
    if (this.length > 0) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechRecognitionResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechRecognitionResult elementAt(int index) => this[index];
  // -- end List<SpeechRecognitionResult> mixins.

  SpeechRecognitionResult item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StyleSheetList")
class _StyleSheetList extends Interceptor
    with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet>
    implements List<StyleSheet>, JavaScriptIndexingBehavior<StyleSheet> {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  StyleSheet operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("StyleSheet", "#[#]", this, index);
  }

  void operator []=(int index, StyleSheet value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<StyleSheet> mixins.
  // StyleSheet is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  StyleSheet get first {
    if (this.length > 0) {
      return JS('StyleSheet', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  StyleSheet get last {
    int len = this.length;
    if (len > 0) {
      return JS('StyleSheet', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  StyleSheet get single {
    int len = this.length;
    if (len == 1) {
      return JS('StyleSheet', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  StyleSheet elementAt(int index) => this[index];
  // -- end List<StyleSheet> mixins.

  CssStyleSheet __getter__(String name) native;

  StyleSheet item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SubtleCrypto")
abstract class _SubtleCrypto extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _SubtleCrypto._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USB")
abstract class _USB extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _USB._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBAlternateInterface")
abstract class _USBAlternateInterface extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBAlternateInterface._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBAlternateInterface(
      _USBInterface deviceInterface, int alternateSetting) {
    return _USBAlternateInterface._create_1(deviceInterface, alternateSetting);
  }
  static _USBAlternateInterface _create_1(deviceInterface, alternateSetting) =>
      JS('_USBAlternateInterface', 'new USBAlternateInterface(#,#)',
          deviceInterface, alternateSetting);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBConfiguration")
abstract class _USBConfiguration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBConfiguration._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBConfiguration(_USBDevice device, int configurationValue) {
    return _USBConfiguration._create_1(device, configurationValue);
  }
  static _USBConfiguration _create_1(device, configurationValue) => JS(
      '_USBConfiguration',
      'new USBConfiguration(#,#)',
      device,
      configurationValue);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBConnectionEvent")
abstract class _USBConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory _USBConnectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBConnectionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return _USBConnectionEvent._create_1(type, eventInitDict_1);
  }
  static _USBConnectionEvent _create_1(type, eventInitDict) => JS(
      '_USBConnectionEvent',
      'new USBConnectionEvent(#,#)',
      type,
      eventInitDict);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBDevice")
abstract class _USBDevice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBDevice._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBEndpoint")
abstract class _USBEndpoint extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBEndpoint._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBEndpoint(
      _USBAlternateInterface alternate, int endpointNumber, String direction) {
    return _USBEndpoint._create_1(alternate, endpointNumber, direction);
  }
  static _USBEndpoint _create_1(alternate, endpointNumber, direction) => JS(
      '_USBEndpoint',
      'new USBEndpoint(#,#,#)',
      alternate,
      endpointNumber,
      direction);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBInTransferResult")
abstract class _USBInTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBInTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBInTransferResult(String status, [ByteData data]) {
    if (data != null) {
      return _USBInTransferResult._create_1(status, data);
    }
    return _USBInTransferResult._create_2(status);
  }
  static _USBInTransferResult _create_1(status, data) =>
      JS('_USBInTransferResult', 'new USBInTransferResult(#,#)', status, data);
  static _USBInTransferResult _create_2(status) =>
      JS('_USBInTransferResult', 'new USBInTransferResult(#)', status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBInterface")
abstract class _USBInterface extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBInterface._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBInterface(_USBConfiguration configuration, int interfaceNumber) {
    return _USBInterface._create_1(configuration, interfaceNumber);
  }
  static _USBInterface _create_1(configuration, interfaceNumber) => JS(
      '_USBInterface', 'new USBInterface(#,#)', configuration, interfaceNumber);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousInTransferPacket")
abstract class _USBIsochronousInTransferPacket extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousInTransferPacket._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousInTransferPacket(String status, [ByteData data]) {
    if (data != null) {
      return _USBIsochronousInTransferPacket._create_1(status, data);
    }
    return _USBIsochronousInTransferPacket._create_2(status);
  }
  static _USBIsochronousInTransferPacket _create_1(status, data) => JS(
      '_USBIsochronousInTransferPacket',
      'new USBIsochronousInTransferPacket(#,#)',
      status,
      data);
  static _USBIsochronousInTransferPacket _create_2(status) => JS(
      '_USBIsochronousInTransferPacket',
      'new USBIsochronousInTransferPacket(#)',
      status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousInTransferResult")
abstract class _USBIsochronousInTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousInTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousInTransferResult(
      List<_USBIsochronousInTransferPacket> packets,
      [ByteData data]) {
    if (data != null) {
      return _USBIsochronousInTransferResult._create_1(packets, data);
    }
    return _USBIsochronousInTransferResult._create_2(packets);
  }
  static _USBIsochronousInTransferResult _create_1(packets, data) => JS(
      '_USBIsochronousInTransferResult',
      'new USBIsochronousInTransferResult(#,#)',
      packets,
      data);
  static _USBIsochronousInTransferResult _create_2(packets) => JS(
      '_USBIsochronousInTransferResult',
      'new USBIsochronousInTransferResult(#)',
      packets);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousOutTransferPacket")
abstract class _USBIsochronousOutTransferPacket extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousOutTransferPacket._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousOutTransferPacket(String status, [int bytesWritten]) {
    if (bytesWritten != null) {
      return _USBIsochronousOutTransferPacket._create_1(status, bytesWritten);
    }
    return _USBIsochronousOutTransferPacket._create_2(status);
  }
  static _USBIsochronousOutTransferPacket _create_1(status, bytesWritten) => JS(
      '_USBIsochronousOutTransferPacket',
      'new USBIsochronousOutTransferPacket(#,#)',
      status,
      bytesWritten);
  static _USBIsochronousOutTransferPacket _create_2(status) => JS(
      '_USBIsochronousOutTransferPacket',
      'new USBIsochronousOutTransferPacket(#)',
      status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousOutTransferResult")
abstract class _USBIsochronousOutTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousOutTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousOutTransferResult(
      List<_USBIsochronousOutTransferPacket> packets) {
    return _USBIsochronousOutTransferResult._create_1(packets);
  }
  static _USBIsochronousOutTransferResult _create_1(packets) => JS(
      '_USBIsochronousOutTransferResult',
      'new USBIsochronousOutTransferResult(#)',
      packets);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBOutTransferResult")
abstract class _USBOutTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBOutTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBOutTransferResult(String status, [int bytesWritten]) {
    if (bytesWritten != null) {
      return _USBOutTransferResult._create_1(status, bytesWritten);
    }
    return _USBOutTransferResult._create_2(status);
  }
  static _USBOutTransferResult _create_1(status, bytesWritten) => JS(
      '_USBOutTransferResult',
      'new USBOutTransferResult(#,#)',
      status,
      bytesWritten);
  static _USBOutTransferResult _create_2(status) =>
      JS('_USBOutTransferResult', 'new USBOutTransferResult(#)', status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class _WindowTimers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() {
    throw new UnsupportedError("Not supported");
  }

  int _setInterval_String(String handler, [int timeout, Object arguments]);

  int _setTimeout_String(String handler, [int timeout, Object arguments]);

  void _clearInterval([int handle]);

  void _clearTimeout([int handle]);

  int _setInterval(Object handler, [int timeout]);

  int _setTimeout(Object handler, [int timeout]);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerLocation")
abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() {
    throw new UnsupportedError("Not supported");
  }

  // From URLUtilsReadOnly

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerNavigator")
abstract class _WorkerNavigator extends NavigatorConcurrentHardware
    implements NavigatorOnLine, NavigatorID {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() {
    throw new UnsupportedError("Not supported");
  }

  // From NavigatorID

  // From NavigatorOnLine

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Worklet")
abstract class _Worklet extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Worklet._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class _AttributeMap extends MapBase<String, String> {
  final Element _element;

  _AttributeMap(this._element);

  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  Map<K, V> cast<K, V>() => Map.castFrom<String, String, K, V>(this);
  bool containsValue(Object value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        keys.add(attr.name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        values.add(attr.value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(_Attr node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {
  _ElementAttributeMap(Element element) : super(element);

  bool containsKey(Object key) {
    return _element._hasAttribute(key);
  }

  String operator [](Object key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  @pragma('dart2js:tryInline')
  String remove(Object key) => key is String ? _remove(_element, key) : null;

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(_Attr node) => node._namespaceUri == null;

  // Inline this because almost all call sites of [remove] do not use [value],
  // and the annotations on the `getAttribute` call allow it to be removed.
  @pragma('dart2js:tryInline')
  static String _remove(Element element, String key) {
    String value = JS(
        // throws:null(1) is not accurate since [key] could be malformed, but
        // [key] is checked again by `removeAttributeNS`.
        'returns:String|Null;depends:all;effects:none;throws:null(1)',
        '#.getAttribute(#)',
        element,
        key);
    JS('', '#.removeAttribute(#)', element, key);
    return value;
  }
}

/**
 * Wrapper to expose namespaced attributes as a typed map.
 */
class _NamespacedAttributeMap extends _AttributeMap {
  final String _namespace;

  _NamespacedAttributeMap(Element element, this._namespace) : super(element);

  bool containsKey(Object key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](Object key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  @pragma('dart2js:tryInline')
  String remove(Object key) =>
      key is String ? _remove(_namespace, _element, key) : null;

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(_Attr node) => node._namespaceUri == _namespace;

  // Inline this because almost all call sites of [remove] do not use the
  // returned [value], and the annotations on the `getAttributeNS` call allow it
  // to be removed.
  @pragma('dart2js:tryInline')
  static String _remove(String namespace, Element element, String key) {
    String value = JS(
        // throws:null(1) is not accurate since [key] could be malformed, but
        // [key] is checked again by `removeAttributeNS`.
        'returns:String|Null;depends:all;effects:none;throws:null(1)',
        '#.getAttributeNS(#, #)',
        element,
        namespace,
        key);
    JS('', '#.removeAttributeNS(#, #)', element, namespace, key);
    return value;
  }
}

/**
 * Provides a Map abstraction on top of data-* attributes, similar to the
 * dataSet in the old DOM.
 */
class _DataAttributeMap extends MapBase<String, String> {
  final Map<String, String> _attributes;

  _DataAttributeMap(this._attributes);

  // interface Map

  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  Map<K, V> cast<K, V>() => Map.castFrom<String, String, K, V>(this);
  // TODO: Use lazy iterator when it is available on Map.
  bool containsValue(Object value) => values.any((v) => v == value);

  bool containsKey(Object key) => _attributes.containsKey(_attr(key));

  String operator [](Object key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
      _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(Object key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * capitalize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering
 *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
 *   from WHATWG.
 * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
 *   from WHATWG.
 */
abstract class CanvasImageSource {}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation
   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
   *   from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
   *   from MDN.
   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
   *   from WHATWG.
   */
  void postMessage(var message, String targetOrigin,
      [List<MessagePort> messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {
  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   *
   * If this corresponds to one element, returns `true` if [value] is present
   * after the operation, and returns `false` if [value] is absent after the
   * operation.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To toggle multiple classes, use
   * [toggleAll].
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.
   */
  bool contains(Object value);

  /**
   * Add the class [value] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this CssClassSet corresponds to one element. Returns true if [value] was
   * added to the set, otherwise false.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To add multiple classes use
   * [addAll].
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To remove multiple classes, use
   * [removeAll].
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void removeAll(Iterable<Object> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {
  _ContentCssRect(Element element) : super(element);

  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  set height(dynamic newHeight) {
    if (newHeight is Dimension) {
      Dimension newHeightAsDimension = newHeight;
      if (newHeightAsDimension.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else if (newHeight is num) {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    } else {
      throw new ArgumentError("newHeight is not a Dimension or num");
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(dynamic newWidth) {
    if (newWidth is Dimension) {
      Dimension newWidthAsDimension = newWidth;
      if (newWidthAsDimension.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else if (newWidth is num) {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    } else {
      throw new ArgumentError("newWidth is not a Dimension or num");
    }
  }

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(List<Element> elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect implements Rectangle<num> {
  Element _element;

  CssRect(this._element);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  set height(dynamic newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  set width(dynamic newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(
      List<String> dimensions, String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(
                styles.getPropertyValue('$augmentingMeasurement-$measurement'))
            .value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
        val -= new Dimension.css(
                styles.getPropertyValue('${_PADDING}-$measurement'))
            .value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
        val -= new Dimension.css(
                styles.getPropertyValue('border-${measurement}-width'))
            .value;
      }
    }
    return val;
  }

  // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math
  // Ideally we would provide a RectangleMixin class that provides this implementation.
  // In an ideal world we would exp
  /** The x-coordinate of the right edge. */
  num get right => left + width;
  /** The y-coordinate of the bottom edge. */
  num get bottom => top + height;

  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        right == other.right &&
        bottom == other.bottom;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, right.hashCode, bottom.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or `null` if they don't
   * intersect.
   */
  Rectangle<num> intersection(Rectangle<num> other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle<num> boundingBox(Rectangle<num> other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle<num>(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point<num> get topLeft => new Point<num>(this.left, this.top);
  Point<num> get topRight => new Point<num>(this.left + this.width, this.top);
  Point<num> get bottomRight =>
      new Point<num>(this.left + this.width, this.top + this.height);
  Point<num> get bottomLeft =>
      new Point<num>(this.left, this.top + this.height);
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;

  // TODO(sra): Perhaps we should store the DomTokenList instead.
  final List<CssClassSetImpl> _sets;

  factory _MultiElementCssClassSet(Iterable<Element> elements) {
    return new _MultiElementCssClassSet._(elements,
        new List<CssClassSetImpl>.from(elements.map((Element e) => e.classes)));
  }

  _MultiElementCssClassSet._(this._elementIterable, this._sets);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = s.join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify(f(Set<String> s)) {
    _sets.forEach((CssClassSetImpl e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * TODO(sra): It seems wrong to collect a 'changed' flag like this when the
   * underlying toggle returns an 'is set' flag.
   */
  bool toggle(String value, [bool shouldAdd]) => _sets.fold(
      false,
      (bool changed, CssClassSetImpl e) =>
          e.toggle(value, shouldAdd) || changed);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _sets.fold(
      false, (bool changed, CssClassSetImpl e) => e.remove(value) || changed);
}

class _ElementCssClassSet extends CssClassSetImpl {
  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    _element.className = s.join(' ');
  }

  int get length => _classListLength(_classListOf(_element));
  bool get isEmpty => length == 0;
  bool get isNotEmpty => length != 0;

  void clear() {
    _element.className = '';
  }

  bool contains(Object value) {
    return _contains(_element, value);
  }

  bool add(String value) {
    return _add(_element, value);
  }

  bool remove(Object value) {
    return value is String && _remove(_element, value);
  }

  bool toggle(String value, [bool shouldAdd]) {
    return _toggle(_element, value, shouldAdd);
  }

  void addAll(Iterable<String> iterable) {
    _addAll(_element, iterable);
  }

  void removeAll(Iterable<Object> iterable) {
    _removeAll(_element, iterable);
  }

  void retainAll(Iterable<Object> iterable) {
    _removeWhere(_element, iterable.toSet().contains, false);
  }

  void removeWhere(bool test(String name)) {
    _removeWhere(_element, test, true);
  }

  void retainWhere(bool test(String name)) {
    _removeWhere(_element, test, false);
  }

  static bool _contains(Element _element, Object value) {
    return value is String && _classListContains(_classListOf(_element), value);
  }

  @pragma('dart2js:tryInline')
  static bool _add(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    // Compute returned result independently of action upon the set.
    bool added = !_classListContainsBeforeAddOrRemove(list, value);
    _classListAdd(list, value);
    return added;
  }

  @pragma('dart2js:tryInline')
  static bool _remove(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    bool removed = _classListContainsBeforeAddOrRemove(list, value);
    _classListRemove(list, value);
    return removed;
  }

  static bool _toggle(Element _element, String value, bool shouldAdd) {
    // There is no value that can be passed as the second argument of
    // DomTokenList.toggle that behaves the same as passing one argument.
    // `null` is seen as false, meaning 'remove'.
    return shouldAdd == null
        ? _toggleDefault(_element, value)
        : _toggleOnOff(_element, value, shouldAdd);
  }

  static bool _toggleDefault(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    return _classListToggle1(list, value);
  }

  static bool _toggleOnOff(Element _element, String value, bool shouldAdd) {
    DomTokenList list = _classListOf(_element);
    // IE's toggle does not take a second parameter. We would prefer:
    //
    //    return _classListToggle2(list, value, shouldAdd);
    //
    if (shouldAdd) {
      _classListAdd(list, value);
      return true;
    } else {
      _classListRemove(list, value);
      return false;
    }
  }

  static void _addAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (String value in iterable) {
      _classListAdd(list, value);
    }
  }

  static void _removeAll(Element _element, Iterable<Object> iterable) {
    DomTokenList list = _classListOf(_element);
    for (String value in iterable) {
      _classListRemove(list, value);
    }
  }

  static void _removeWhere(
      Element _element, bool test(String name), bool doRemove) {
    DomTokenList list = _classListOf(_element);
    int i = 0;
    while (i < _classListLength(list)) {
      String item = list.item(i);
      if (doRemove == test(item)) {
        _classListRemove(list, item);
      } else {
        ++i;
      }
    }
  }

  // A collection of static methods for DomTokenList. These methods are a
  // work-around for the lack of annotations to express the full behaviour of
  // the DomTokenList methods.

  static DomTokenList _classListOf(Element e) => JS(
      'returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;',
      '#.classList',
      e);

  static int _classListLength(DomTokenList list) =>
      JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list);

  static bool _classListContains(DomTokenList list, String value) =>
      JS('returns:bool;effects:none;depends:all', '#.contains(#)', list, value);

  static bool _classListContainsBeforeAddOrRemove(
          DomTokenList list, String value) =>
      // 'throws:never' is a lie, since 'contains' will throw on an illegal
      // token.  However, we always call this function immediately prior to
      // add/remove/toggle with the same token.  Often the result of 'contains'
      // is unused and the lie makes it possible for the 'contains' instruction
      // to be removed.
      JS('returns:bool;effects:none;depends:all;throws:null(1)',
          '#.contains(#)', list, value);

  static void _classListAdd(DomTokenList list, String value) {
    // list.add(value);
    JS('', '#.add(#)', list, value);
  }

  static void _classListRemove(DomTokenList list, String value) {
    // list.remove(value);
    JS('', '#.remove(#)', list, value);
  }

  static bool _classListToggle1(DomTokenList list, String value) {
    return JS('bool', '#.toggle(#)', list, value);
  }

  static bool _classListToggle2(
      DomTokenList list, String value, bool shouldAdd) {
    return JS('bool', '#.toggle(#, #)', list, value, shouldAdd);
  }
}

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the x-height of a font's baseline to its mean line,
   * generally the height of the letter "x" in the font, which is usually about
   * half the font-size.
   */
  Dimension.ex(this._value) : _unit = 'ex';

  /**
   * Construct a Dimension object from the valid, simple CSS string `cssValue`
   * that represents a distance measurement.
   *
   * This constructor is intended as a convenience method for working with
   * simplistic CSS length measurements. Non-numeric values such as `auto` or
   * `inherit` or invalid CSS will cause this constructor to throw a
   * FormatError.
   */
  Dimension.css(String cssValue) {
    if (cssValue == '') cssValue = '0px';
    if (cssValue.endsWith('%')) {
      _unit = '%';
    } else {
      _unit = cssValue.substring(cssValue.length - 2);
    }
    if (cssValue.contains('.')) {
      _value =
          double.parse(cssValue.substring(0, cssValue.length - _unit.length));
    } else {
      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
    }
  }

  /** Print out the CSS String representation of this value. */
  String toString() {
    return '${_value}${_unit}';
  }

  /** Return a unitless, numerical value of this CSS value. */
  num get value => this._value;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

typedef EventListener(Event event);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A factory to expose DOM events as Streams.
 */
class EventStreamProvider<T extends Event> {
  final String _eventType;

  const EventStreamProvider(this._eventType);

  /**
   * Gets a [Stream] for this event type, on the specified target.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forTarget(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
   *
   * See also:
   *
   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
   *   from MDN.
   */
  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
      new _EventStream<T>(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
   *   from MDN.
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
   *   from MDN.
   */
  ElementStream<T> _forElementList(ElementList<Element> e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   *   from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      this;
  bool get isBroadcast => true;

  // TODO(9757): Inlining should be smart and inline only when inlining would
  // enable scalar replacement of an immediately allocated receiver.
  @pragma('dart2js:tryInline')
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

bool _matchesWithAncestors(Event event, String selector) {
  var target = event.target;
  return target is Element ? target.matchesWithAncestors(selector) : false;
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture)
      : super(target, eventType, useCapture);

  Stream<T> matches(String selector) =>
      this.where((event) => _matchesWithAncestors(event, selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
      new _EventStreamSubscription<T>(
          this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) =>
      this.where((event) => _matchesWithAncestors(event, selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    var pool = new _StreamPool<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      this;
  bool get isBroadcast => true;
}

// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  EventListener _onData;
  final bool _useCapture;

  // TODO(leafp): It would be better to write this as
  // _onData = onData == null ? null :
  //   onData is void Function(Event)
  //     ? _wrapZone<Event>(onData)
  //     : _wrapZone<Event>((e) => onData(e as T))
  // In order to support existing tests which pass the wrong type of events but
  // use a more general listener, without causing as much slowdown for things
  // which are typed correctly.  But this currently runs afoul of restrictions
  // on is checks for compatibility with the VM.
  _EventStreamSubscription(
      this._target, this._eventType, void onData(T event), this._useCapture)
      : _onData = onData == null
            ? null
            : _wrapZone<Event>((e) => (onData as dynamic)(e)) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return null;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return null;
  }

  bool get _canceled => _target == null;

  void onData(void handleData(T event)) {
    if (_canceled) {
      throw new StateError("Subscription has been canceled.");
    }
    // Remove current event listener.
    _unlisten();
    _onData = _wrapZone<Event>(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future<E> asFuture<E>([E futureValue]) {
    // We just need a future that will never succeed or fail.
    var completer = new Completer<E>();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    return _streamController.stream.listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller =
        new StreamController<T>.broadcast(sync: true, onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError, onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {
  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList<Element> e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(
        e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {
  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::autofocus',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      : uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From List<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE ||
        keyCode == QUESTION_MARK ||
        keyCode == NUM_PLUS ||
        keyCode == NUM_MINUS ||
        keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION ||
        keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON ||
        keyCode == DASH ||
        keyCode == EQUALS ||
        keyCode == FF_EQUALS ||
        keyCode == COMMA ||
        keyCode == PERIOD ||
        keyCode == SLASH ||
        keyCode == APOSTROPHE ||
        keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET ||
        keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch (keyCode) {
      case KeyCode.ALT:
        return _KeyName.ALT;
      case KeyCode.BACKSPACE:
        return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK:
        return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL:
        return _KeyName.CONTROL;
      case KeyCode.DELETE:
        return _KeyName.DEL;
      case KeyCode.DOWN:
        return _KeyName.DOWN;
      case KeyCode.END:
        return _KeyName.END;
      case KeyCode.ENTER:
        return _KeyName.ENTER;
      case KeyCode.ESC:
        return _KeyName.ESC;
      case KeyCode.F1:
        return _KeyName.F1;
      case KeyCode.F2:
        return _KeyName.F2;
      case KeyCode.F3:
        return _KeyName.F3;
      case KeyCode.F4:
        return _KeyName.F4;
      case KeyCode.F5:
        return _KeyName.F5;
      case KeyCode.F6:
        return _KeyName.F6;
      case KeyCode.F7:
        return _KeyName.F7;
      case KeyCode.F8:
        return _KeyName.F8;
      case KeyCode.F9:
        return _KeyName.F9;
      case KeyCode.F10:
        return _KeyName.F10;
      case KeyCode.F11:
        return _KeyName.F11;
      case KeyCode.F12:
        return _KeyName.F12;
      case KeyCode.HOME:
        return _KeyName.HOME;
      case KeyCode.INSERT:
        return _KeyName.INSERT;
      case KeyCode.LEFT:
        return _KeyName.LEFT;
      case KeyCode.META:
        return _KeyName.META;
      case KeyCode.NUMLOCK:
        return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN:
        return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP:
        return _KeyName.PAGE_UP;
      case KeyCode.PAUSE:
        return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN:
        return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT:
        return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK:
        return _KeyName.SCROLL;
      case KeyCode.SHIFT:
        return _KeyName.SHIFT;
      case KeyCode.SPACE:
        return _KeyName.SPACEBAR;
      case KeyCode.TAB:
        return _KeyName.TAB;
      case KeyCode.UP:
        return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default:
        return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {
  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {
  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF = "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND = "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyEvent> _keyDownList = <KeyEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler =
        new _KeyboardEventHandler.initializeAllEventListeners(_type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type)
      : _stream = new _CustomKeyEventStreamImpl('event'),
        _target = null,
        super(_EVENT_TYPE);

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target)
      : super(_EVENT_TYPE) {
    Element.keyDownEvent
        .forTarget(_target, useCapture: true)
        .listen(processKeyDown);
    Element.keyPressEvent
        .forTarget(_target, useCapture: true)
        .listen(processKeyPress);
    Element.keyUpEvent
        .forTarget(_target, useCapture: true)
        .listen(processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) &&
          event.charCode >= "A".codeUnits[0] &&
          event.charCode <= "Z".codeUnits[0] &&
          event.charCode + _ROMAN_ALPHABET_OFFSET ==
              prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the character code returned from a keyDown [event], try to ascertain
   * and return the corresponding charCode for the character that was pressed.
   * This information is not shown to the user, but used to help polyfill
   * keypress events.
   */
  int _findCharCodeKeyDown(KeyboardEvent event) {
    if (event.location == 3) {
      // Numpad keys.
      switch (event.keyCode) {
        case KeyCode.NUM_ZERO:
          // Even though this function returns _charCodes_, for some cases the
          // KeyCode == the charCode we want, in which case we use the keycode
          // constant for readability.
          return KeyCode.ZERO;
        case KeyCode.NUM_ONE:
          return KeyCode.ONE;
        case KeyCode.NUM_TWO:
          return KeyCode.TWO;
        case KeyCode.NUM_THREE:
          return KeyCode.THREE;
        case KeyCode.NUM_FOUR:
          return KeyCode.FOUR;
        case KeyCode.NUM_FIVE:
          return KeyCode.FIVE;
        case KeyCode.NUM_SIX:
          return KeyCode.SIX;
        case KeyCode.NUM_SEVEN:
          return KeyCode.SEVEN;
        case KeyCode.NUM_EIGHT:
          return KeyCode.EIGHT;
        case KeyCode.NUM_NINE:
          return KeyCode.NINE;
        case KeyCode.NUM_MULTIPLY:
          return 42; // Char code for *
        case KeyCode.NUM_PLUS:
          return 43; // +
        case KeyCode.NUM_MINUS:
          return 45; // -
        case KeyCode.NUM_PERIOD:
          return 46; // .
        case KeyCode.NUM_DIVISION:
          return 47; // /
      }
    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
      // Set the "char code" for key down as the lower case letter. Again, this
      // will not show up for the user, but will be helpful in estimating
      // keyCode locations and other information during the keyPress event.
      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
    }
    switch (event.keyCode) {
      case KeyCode.SEMICOLON:
        return KeyCode.FF_SEMICOLON;
      case KeyCode.EQUALS:
        return KeyCode.FF_EQUALS;
      case KeyCode.COMMA:
        return 44; // Ascii value for ,
      case KeyCode.DASH:
        return 45; // -
      case KeyCode.PERIOD:
        return 46; // .
      case KeyCode.SLASH:
        return 47; // /
      case KeyCode.APOSTROPHE:
        return 96; // `
      case KeyCode.OPEN_SQUARE_BRACKET:
        return 91; // [
      case KeyCode.BACKSLASH:
        return 92; // \
      case KeyCode.CLOSE_SQUARE_BRACKET:
        return 93; // ]
      case KeyCode.SINGLE_QUOTE:
        return 39; // '
    }
    return event.keyCode;
  }

  /**
   * Returns true if the key fires a keypress event in the current browser.
   */
  bool _firesKeyPressEvent(KeyEvent event) {
    if (!Device.isIE && !Device.isWebKit) {
      return true;
    }

    if (Device.userAgent.contains('Mac') && event.altKey) {
      return KeyCode.isCharacterKey(event.keyCode);
    }

    // Alt but not AltGr which is represented as Alt+Ctrl.
    if (event.altKey && !event.ctrlKey) {
      return false;
    }

    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
    if (!event.shiftKey &&
        (_keyDownList.last.keyCode == KeyCode.CTRL ||
            _keyDownList.last.keyCode == KeyCode.ALT ||
            Device.userAgent.contains('Mac') &&
                _keyDownList.last.keyCode == KeyCode.META)) {
      return false;
    }

    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
    if (Device.isWebKit &&
        event.ctrlKey &&
        event.shiftKey &&
        (event.keyCode == KeyCode.BACKSLASH ||
            event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
            event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
            event.keyCode == KeyCode.TILDE ||
            event.keyCode == KeyCode.SEMICOLON ||
            event.keyCode == KeyCode.DASH ||
            event.keyCode == KeyCode.EQUALS ||
            event.keyCode == KeyCode.COMMA ||
            event.keyCode == KeyCode.PERIOD ||
            event.keyCode == KeyCode.SLASH ||
            event.keyCode == KeyCode.APOSTROPHE ||
            event.keyCode == KeyCode.SINGLE_QUOTE)) {
      return false;
    }

    switch (event.keyCode) {
      case KeyCode.ENTER:
        // IE9 does not fire keypress on ENTER.
        return !Device.isIE;
      case KeyCode.ESC:
        return !Device.isWebKit;
    }

    return KeyCode.isCharacterKey(event.keyCode);
  }

  /**
   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
   * Opera all use).
   */
  int _normalizeKeyCodes(KeyboardEvent event) {
    // Note: This may change once we get input about non-US keyboards.
    if (Device.isFirefox) {
      switch (event.keyCode) {
        case KeyCode.FF_EQUALS:
          return KeyCode.EQUALS;
        case KeyCode.FF_SEMICOLON:
          return KeyCode.SEMICOLON;
        case KeyCode.MAC_FF_META:
          return KeyCode.META;
        case KeyCode.WIN_KEY_FF_LINUX:
          return KeyCode.WIN_KEY;
      }
    }
    return event.keyCode;
  }

  /** Handle keydown events. */
  void processKeyDown(KeyboardEvent e) {
    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
    // before we've caught a key-up event.  If the last-key was one of these
    // we reset the state.
    if (_keyDownList.length > 0 &&
        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
            _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
            Device.userAgent.contains('Mac') &&
                _keyDownList.last.keyCode == KeyCode.META &&
                !e.metaKey)) {
      _keyDownList.clear();
    }

    var event = new KeyEvent.wrap(e);
    event._shadowKeyCode = _normalizeKeyCodes(event);
    // Technically a "keydown" event doesn't have a charCode. This is
    // calculated nonetheless to provide us with more information in giving
    // as much information as possible on keypress about keycode and also
    // charCode.
    event._shadowCharCode = _findCharCodeKeyDown(event);
    if (_keyDownList.length > 0 &&
        event.keyCode != _keyDownList.last.keyCode &&
        !_firesKeyPressEvent(event)) {
      // Some browsers have quirks not firing keypress events where all other
      // browsers do. This makes them more consistent.
      processKeyPress(e);
    }
    _keyDownList.add(event);
    _stream.add(event);
  }

  /** Handle keypress events. */
  void processKeyPress(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    // IE reports the character code in the keyCode field for keypress events.
    // There are two exceptions however, Enter and Escape.
    if (Device.isIE) {
      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
        e._shadowCharCode = 0;
      } else {
        e._shadowCharCode = e.keyCode;
      }
    } else if (Device.isOpera) {
      // Opera reports the character code in the keyCode field.
      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
    }
    // Now we guesstimate about what the keycode is that was actually
    // pressed, given previous keydown information.
    e._shadowKeyCode = _determineKeyCodeForKeypress(e);

    // Correct the key value for certain browser-specific quirks.
    if (e._shadowKeyIdentifier != null &&
        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
      // This is needed for Safari Windows because it currently doesn't give a
      // keyCode/which for non printable keys.
      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
    }
    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
    _stream.add(e);
  }

  /** Handle keyup events. */
  void processKeyUp(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    KeyboardEvent toRemove = null;
    for (var key in _keyDownList) {
      if (key.keyCode == e.keyCode) {
        toRemove = key;
      }
    }
    if (toRemove != null) {
      _keyDownList.removeWhere((element) => element == toRemove);
    } else if (_keyDownList.length > 0) {
      // This happens when we've reached some international keyboard case we
      // haven't accounted for or we haven't correctly eliminated all browser
      // inconsistencies. Filing bugs on when this is reached is welcome!
      _keyDownList.removeLast();
    }
    _stream.add(e);
  }
}

/**
 * Records KeyboardEvents that occur on a particular element, and provides a
 * stream of outgoing KeyEvents with cross-browser consistent keyCode and
 * charCode values despite the fact that a multitude of browsers that have
 * varying keyboard default behavior.
 *
 * Example usage:
 *
 *     KeyboardEventStream.onKeyDown(document.body).listen(
 *         keydownHandlerTest);
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyboardEventStream {
  /** Named constructor to produce a stream for onKeyPress events. */
  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
      new _KeyboardEventHandler('keypress').forTarget(target);

  /** Named constructor to produce a stream for onKeyUp events. */
  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
      new _KeyboardEventHandler('keyup').forTarget(target);

  /** Named constructor to produce a stream for onKeyDown events. */
  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
      new _KeyboardEventHandler('keydown').forTarget(target);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Class which helps construct standard node validation policies.
 *
 * By default this will not accept anything, but the 'allow*' functions can be
 * used to expand what types of elements or attributes are allowed.
 *
 * All allow functions are additive- elements will be accepted if they are
 * accepted by any specific rule.
 *
 * It is important to remember that sanitization is not just intended to prevent
 * cross-site scripting attacks, but also to prevent information from being
 * displayed in unexpected ways. For example something displaying basic
 * formatted text may not expect `<video>` tags to appear. In this case an
 * empty NodeValidatorBuilder with just [allowTextElements] might be
 * appropriate.
 */
class NodeValidatorBuilder implements NodeValidator {
  final List<NodeValidator> _validators = <NodeValidator>[];

  NodeValidatorBuilder() {}

  /**
   * Creates a new NodeValidatorBuilder which accepts common constructs.
   *
   * By default this will accept HTML5 elements and attributes with the default
   * [UriPolicy] and templating elements.
   *
   * Notable syntax which is filtered:
   *
   * * Only known-good HTML5 elements and attributes are allowed.
   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
   * specify additional URI policies.
   * * Inline-styles are not allowed.
   * * Custom element tags are disallowed, use [allowCustomElement].
   * * Custom tags extensions are disallowed, use [allowTagExtension].
   * * SVG Elements are not allowed, use [allowSvg].
   *
   * For scenarios where the HTML should only contain formatted text
   * [allowTextElements] is more appropriate.
   *
   * Use [allowSvg] to allow SVG elements.
   */
  NodeValidatorBuilder.common() {
    allowHtml5();
    allowTemplating();
  }

  /**
   * Allows navigation elements- Form and Anchor tags, along with common
   * attributes.
   *
   * The UriPolicy can be used to restrict the locations the navigation elements
   * are allowed to direct to. By default this will use the default [UriPolicy].
   */
  void allowNavigation([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
  }

  /**
   * Allows image elements.
   *
   * The UriPolicy can be used to restrict the locations the images may be
   * loaded from. By default this will use the default [UriPolicy].
   */
  void allowImages([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowImages(uriPolicy));
  }

  /**
   * Allow basic text elements.
   *
   * This allows a subset of HTML5 elements, specifically just these tags and
   * no attributes.
   *
   * * B
   * * BLOCKQUOTE
   * * BR
   * * EM
   * * H1
   * * H2
   * * H3
   * * H4
   * * H5
   * * H6
   * * HR
   * * I
   * * LI
   * * OL
   * * P
   * * SPAN
   * * UL
   */
  void allowTextElements() {
    add(new _SimpleNodeValidator.allowTextElements());
  }

  /**
   * Allow inline styles on elements.
   *
   * If [tagName] is not specified then this allows inline styles on all
   * elements. Otherwise tagName limits the styles to the specified elements.
   */
  void allowInlineStyles({String tagName}) {
    if (tagName == null) {
      tagName = '*';
    } else {
      tagName = tagName.toUpperCase();
    }
    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
  }

  /**
   * Allow common safe HTML5 elements and attributes.
   *
   * This list is based off of the Caja whitelists at:
   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
   *
   * Common things which are not allowed are script elements, style attributes
   * and any script handlers.
   */
  void allowHtml5({UriPolicy uriPolicy}) {
    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
  }

  /**
   * Allow SVG elements and attributes except for known bad ones.
   */
  void allowSvg() {
    add(new _SvgNodeValidator());
  }

  /**
   * Allow custom elements with the specified tag name and specified attributes.
   *
   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
   * but will not allow tag extensions. Use [allowTagExtension] to allow
   * tag extensions.
   */
  void allowCustomElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    var tagNameUpper = tagName.toUpperCase();
    var attrs = attributes
        ?.map<String>((name) => '$tagNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map<String>((name) => '$tagNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy, [tagNameUpper], attrs, uriAttrs, false, true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs = attributes
        ?.map<String>((name) => '$baseNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map<String>((name) => '$baseNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(uriPolicy,
        [tagNameUpper, baseNameUpper], attrs, uriAttrs, true, false));
  }

  void allowElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    allowCustomElement(tagName,
        uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators
        .any((v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements = new Set<String>();
  final Set<String> allowedAttributes = new Set<String>();
  final Set<String> allowedUriAttributes = new Set<String>();
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'A',
      'FORM'
    ], allowedAttributes: const [
      'A::accesskey',
      'A::coords',
      'A::hreflang',
      'A::name',
      'A::shape',
      'A::tabindex',
      'A::target',
      'A::type',
      'FORM::accept',
      'FORM::autocomplete',
      'FORM::enctype',
      'FORM::method',
      'FORM::name',
      'FORM::novalidate',
      'FORM::target',
    ], allowedUriAttributes: const [
      'A::href',
      'FORM::action',
    ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'IMG'
    ], allowedAttributes: const [
      'IMG::align',
      'IMG::alt',
      'IMG::border',
      'IMG::height',
      'IMG::hspace',
      'IMG::ismap',
      'IMG::name',
      'IMG::usemap',
      'IMG::vspace',
      'IMG::width',
    ], allowedUriAttributes: const [
      'IMG::src',
    ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null, allowedElements: const [
      'B',
      'BLOCKQUOTE',
      'BR',
      'EM',
      'H1',
      'H2',
      'H3',
      'H4',
      'H5',
      'H6',
      'HR',
      'I',
      'LI',
      'OL',
      'P',
      'SPAN',
      'UL',
    ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}) {
    this.allowedElements.addAll(allowedElements ?? const []);
    allowedAttributes = allowedAttributes ?? const [];
    allowedUriAttributes = allowedUriAttributes ?? const [];
    var legalAttributes = allowedAttributes
        .where((x) => !_Html5NodeValidator._uriAttributes.contains(x));
    var extraUriAttributes = allowedAttributes
        .where((x) => _Html5NodeValidator._uriAttributes.contains(x));
    this.allowedAttributes.addAll(legalAttributes);
    this.allowedUriAttributes.addAll(allowedUriAttributes);
    this.allowedUriAttributes.addAll(extraUriAttributes);
  }

  bool allowsElement(Element element) {
    return allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(
      UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag)
      : this.allowTypeExtension = allowTypeExtension == true,
        this.allowCustomTag = allowCustomTag == true,
        super(uriPolicy,
            allowedElements: allowedElements,
            allowedAttributes: allowedAttributes,
            allowedUriAttributes: allowedUriAttributes);

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
            allowedElements.contains(Element._safeTagName(element));
      }
    }
    return allowCustomTag &&
        allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (allowsElement(element)) {
      if (allowTypeExtension &&
          attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS = const <String>[
    'bind',
    'if',
    'ref',
    'repeat',
    'syntax'
  ];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator()
      : _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS),
        super(null,
            allowedElements: ['TEMPLATE'],
            allowedAttributes:
                _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')) {}

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "") {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}

class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    // Firefox 37 has issues with creating foreign elements inside a
    // foreignobject tag as SvgElement. We don't want foreignobject contents
    // anyway, so just remove the whole tree outright. And we can't rely
    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
    if (element is svg.SvgElement &&
        Element._safeTagName(element) == 'foreignObject') {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List<Node> _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator<E>(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) {
    _list.add(element);
  }

  bool remove(Object element) => _list.remove(element);

  void clear() {
    _list.clear();
  }

  // List APIs

  E operator [](int index) => _list[index];

  void operator []=(int index, E value) {
    _list[index] = value;
  }

  set length(int newLength) {
    _list.length = newLength;
  }

  void sort([int compare(E a, E b)]) {
    // Implicit downcast on argument from Node to E-extends-Node.
    _list.sort((Node a, Node b) => compare(a, b));
  }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) =>
      _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index);

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) {
    _list.removeRange(start, end);
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E extends Node> implements Iterator<E> {
  Iterator<Node> _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _iterator.current;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class _HttpRequestUtils {
  // Helper for factory HttpRequest.get
  static HttpRequest get(
      String url, onComplete(HttpRequest request), bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length; // Cache array length for faster access.
  int _position;
  T _current;

  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class Console {
  const Console._safe();
  static const Console _safeConsole = const Console._safe();

  bool get _isConsoleDefined => JS('bool', 'typeof console != "undefined"');

  MemoryInfo get memory =>
      _isConsoleDefined ? JS('MemoryInfo', 'window.console.memory') : null;

  void assertCondition(bool condition, Object arg) => _isConsoleDefined
      ? JS('void', 'window.console.assertCondition(#, #)', condition, arg)
      : null;

  void clear(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.clear(#)', arg) : null;

  void count(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.count(#)', arg) : null;

  void debug(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.debug(#)', arg) : null;

  void dir(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.dir(#)', arg) : null;

  void dirxml(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.dirxml(#)', arg) : null;

  void error(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.error(#)', arg) : null;

  void group(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.group(#)', arg) : null;

  void groupCollapsed(Object arg) => _isConsoleDefined
      ? JS('void', 'window.console.groupCollapsed(#)', arg)
      : null;

  void groupEnd() =>
      _isConsoleDefined ? JS('void', 'window.console.groupEnd()') : null;

  void info(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.info(#)', arg) : null;

  void log(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.log(#)', arg) : null;

  void markTimeline(Object arg) => _isConsoleDefined
      ? JS('void', 'window.console.markTimeline(#)', arg)
      : null;

  void profile(String title) =>
      _isConsoleDefined ? JS('void', 'window.console.profile(#)', title) : null;

  void profileEnd(String title) => _isConsoleDefined
      ? JS('void', 'window.console.profileEnd(#)', title)
      : null;

  void table(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.table(#)', arg) : null;

  void time(String title) =>
      _isConsoleDefined ? JS('void', 'window.console.time(#)', title) : null;

  void timeEnd(String title) =>
      _isConsoleDefined ? JS('void', 'window.console.timeEnd(#)', title) : null;

  void timeStamp(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.timeStamp(#)', arg) : null;

  void trace(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.trace(#)', arg) : null;

  void warn(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.warn(#)', arg) : null;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Conversions for Window.  These check if the window is the local
// window, and if it's not, wraps or unwraps it with a secure wrapper.
// We need to test for EventTarget here as well as it's a base type.
// We omit an unwrapper for Window as no methods take a non-local
// window as a parameter.

WindowBase _convertNativeToDart_Window(win) {
  if (win == null) return null;
  return _DOMWindowCrossFrame._createSafe(win);
}

EventTarget _convertNativeToDart_EventTarget(e) {
  if (e == null) {
    return null;
  }
  // Assume it's a Window if it contains the postMessage property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  if (JS('bool', r'"postMessage" in #', e)) {
    var window = _DOMWindowCrossFrame._createSafe(e);
    // If it's a native window.
    if (window is EventTarget) {
      return window;
    }
    return null;
  } else
    return e;
}

EventTarget _convertDartToNative_EventTarget(e) {
  if (e is _DOMWindowCrossFrame) {
    return e._window;
  } else {
    return e;
  }
}

_convertNativeToDart_XHR_Response(o) {
  if (o is Document) {
    return o;
  }
  return convertNativeToDart_SerializedScriptValue(o);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

_callConstructor(constructor, interceptor) {
  return (receiver) {
    setNativeSubclassDispatchRecord(receiver, interceptor);

    // Mirrors uses the constructor property to cache lookups, so we need it to
    // be set correctly, including on IE where it is not automatically picked
    // up from the __proto__.
    JS('', '#.constructor = #.__proto__.constructor', receiver, receiver);
    return JS('', '#(#)', constructor, receiver);
  };
}

_callAttached(receiver) {
  return receiver.attached();
}

_callDetached(receiver) {
  return receiver.detached();
}

_callAttributeChanged(receiver, name, oldValue, newValue) {
  return receiver.attributeChanged(name, oldValue, newValue);
}

_makeCallbackMethod(callback) {
  return JS(
      '',
      '''((function(invokeCallback) {
             return function() {
               return invokeCallback(this);
             };
          })(#))''',
      convertDartClosureToJS(callback, 1));
}

_makeCallbackMethod3(callback) {
  return JS(
      '',
      '''((function(invokeCallback) {
             return function(arg1, arg2, arg3) {
               return invokeCallback(this, arg1, arg2, arg3);
             };
          })(#))''',
      convertDartClosureToJS(callback, 4));
}

/// Checks whether the given [element] correctly extends from the native class
/// with the given [baseClassName]. This method will throw if the base class
/// doesn't match, except when the element extends from `template` and it's base
/// class is `HTMLUnknownElement`. This exclusion is needed to support extension
/// of template elements (used heavily in Polymer 1.0) on IE11 when using the
/// webcomponents-lite.js polyfill.
void _checkExtendsNativeClassOrTemplate(
    Element element, String extendsTag, String baseClassName) {
  if (!JS('bool', '(# instanceof window[#])', element, baseClassName) &&
      !((extendsTag == 'template' &&
          JS('bool', '(# instanceof window["HTMLUnknownElement"])',
              element)))) {
    throw new UnsupportedError('extendsTag does not match base native class');
  }
}

Function _registerCustomElement(context, document, String tag, [Map options]) {
  // Function follows the same pattern as the following JavaScript code for
  // registering a custom element.
  //
  //    var proto = Object.create(HTMLElement.prototype, {
  //        createdCallback: {
  //          value: function() {
  //            window.console.log('here');
  //          }
  //        }
  //    });
  //    document.registerElement('x-foo', { prototype: proto });
  //    ...
  //    var e = document.createElement('x-foo');

  var extendsTagName = '';
  Type type;
  if (options != null) {
    extendsTagName = options['extends'];
    type = options['prototype'];
  }

  var interceptorClass = findInterceptorConstructorForType(type);
  if (interceptorClass == null) {
    throw new ArgumentError(type);
  }

  var interceptor = JS('=Object', '#.prototype', interceptorClass);

  var constructor = findConstructorForNativeSubclassType(type, 'created');
  if (constructor == null) {
    throw new ArgumentError("$type has no constructor called 'created'");
  }

  // Workaround for 13190- use an article element to ensure that HTMLElement's
  // interceptor is resolved correctly.
  getNativeInterceptor(new Element.tag('article'));

  String baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
  if (baseClassName == null) {
    throw new ArgumentError(type);
  }

  if (extendsTagName == null) {
    if (baseClassName != 'HTMLElement') {
      throw new UnsupportedError('Class must provide extendsTag if base '
          'native class is not HtmlElement');
    }
  } else {
    var element = document.createElement(extendsTagName);
    _checkExtendsNativeClassOrTemplate(element, extendsTagName, baseClassName);
  }

  var baseConstructor = JS('=Object', '#[#]', context, baseClassName);

  var properties = JS('=Object', '{}');

  JS(
      'void',
      '#.createdCallback = #',
      properties,
      JS('=Object', '{value: #}',
          _makeCallbackMethod(_callConstructor(constructor, interceptor))));
  JS('void', '#.attachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callAttached)));
  JS('void', '#.detachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callDetached)));
  JS('void', '#.attributeChangedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));

  var baseProto = JS('=Object', '#.prototype', baseConstructor);
  var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);

  setNativeSubclassDispatchRecord(proto, interceptor);

  var opts = JS('=Object', '{prototype: #}', proto);

  if (extendsTagName != null) {
    JS('=Object', '#.extends = #', opts, extendsTagName);
  }

  return JS(
      'JavaScriptFunction', '#.registerElement(#, #)', document, tag, opts);
}

//// Called by Element.created to do validation & initialization.
void _initializeCustomElement(Element e) {
  // TODO(blois): Add validation that this is only in response to an upgrade.
}

/// Dart2JS implementation of ElementUpgrader
class _JSElementUpgrader implements ElementUpgrader {
  var _interceptor;
  var _constructor;
  var _nativeType;

  _JSElementUpgrader(Document document, Type type, String extendsTag) {
    var interceptorClass = findInterceptorConstructorForType(type);
    if (interceptorClass == null) {
      throw new ArgumentError(type);
    }

    _constructor = findConstructorForNativeSubclassType(type, 'created');
    if (_constructor == null) {
      throw new ArgumentError("$type has no constructor called 'created'");
    }

    // Workaround for 13190- use an article element to ensure that HTMLElement's
    // interceptor is resolved correctly.
    getNativeInterceptor(new Element.tag('article'));

    var baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
    if (baseClassName == null) {
      throw new ArgumentError(type);
    }

    if (extendsTag == null) {
      if (baseClassName != 'HTMLElement') {
        throw new UnsupportedError('Class must provide extendsTag if base '
            'native class is not HtmlElement');
      }
      _nativeType = HtmlElement;
    } else {
      var element = document.createElement(extendsTag);
      _checkExtendsNativeClassOrTemplate(element, extendsTag, baseClassName);
      _nativeType = element.runtimeType;
    }

    _interceptor = JS('=Object', '#.prototype', interceptorClass);
  }

  Element upgrade(Element element) {
    // Only exact type matches are supported- cannot be a subclass.
    if (element.runtimeType != _nativeType) {
      // Some browsers may represent non-upgraded elements <x-foo> as
      // UnknownElement and not a plain HtmlElement.
      if (_nativeType != HtmlElement || element.runtimeType != UnknownElement) {
        throw new ArgumentError('element is not subclass of $_nativeType');
      }
    }

    setNativeSubclassDispatchRecord(element, _interceptor);
    JS('', '#(#)', _constructor, element);
    return element;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// TODO(vsm): Unify with Dartium version.
class _DOMWindowCrossFrame implements WindowBase {
  // Private window.  Note, this is a window in another frame, so it
  // cannot be typed as "Window" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  final _window;

  // Fields.
  HistoryBase get history =>
      _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
  LocationBase get location => _LocationCrossFrame._createSafe(
      JS('LocationBase', '#.location', _window));

  // TODO(vsm): Add frames to navigate subframes.  See 2312.

  bool get closed => JS('bool', '#.closed', _window);

  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));

  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));

  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));

  // Methods.
  void close() => JS('void', '#.close()', _window);

  void postMessage(var message, String targetOrigin,
      [List messagePorts = null]) {
    if (messagePorts == null) {
      JS('void', '#.postMessage(#,#)', _window,
          convertDartToNative_SerializedScriptValue(message), targetOrigin);
    } else {
      JS(
          'void',
          '#.postMessage(#,#,#)',
          _window,
          convertDartToNative_SerializedScriptValue(message),
          targetOrigin,
          messagePorts);
    }
  }

  // Implementation support.
  _DOMWindowCrossFrame(this._window);

  static WindowBase _createSafe(w) {
    if (identical(w, window)) {
      return w;
    } else {
      // TODO(vsm): Cache or implement equality.
      registerGlobalObject(w);
      return new _DOMWindowCrossFrame(w);
    }
  }

  // TODO(efortuna): Remove this method. dartbug.com/16814
  Events get on => throw new UnsupportedError(
      'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _addEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void addEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  bool dispatchEvent(Event event) => throw new UnsupportedError(
      'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _removeEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
}

class _LocationCrossFrame implements LocationBase {
  // Private location.  Note, this is a location object in another frame, so it
  // cannot be typed as "Location" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _location;

  set href(String val) => _setHref(_location, val);
  static void _setHref(location, val) {
    JS('void', '#.href = #', location, val);
  }

  // Implementation support.
  _LocationCrossFrame(this._location);

  static LocationBase _createSafe(location) {
    if (identical(location, window.location)) {
      return location;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _LocationCrossFrame(location);
    }
  }
}

class _HistoryCrossFrame implements HistoryBase {
  // Private history.  Note, this is a history object in another frame, so it
  // cannot be typed as "History" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _history;

  void back() => JS('void', '#.back()', _history);

  void forward() => JS('void', '#.forward()', _history);

  void go(int distance) => JS('void', '#.go(#)', _history, distance);

  // Implementation support.
  _HistoryCrossFrame(this._history);

  static HistoryBase _createSafe(h) {
    if (identical(h, window.history)) {
      return h;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _HistoryCrossFrame(h);
    }
  }
}

/**
 * A custom KeyboardEvent that attempts to eliminate cross-browser
 * inconsistencies, and also provide both keyCode and charCode information
 * for all key events (when such information can be determined).
 *
 * KeyEvent tries to provide a higher level, more polished keyboard event
 * information on top of the "raw" [KeyboardEvent].
 *
 * The mechanics of using KeyEvents is a little different from the underlying
 * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
 * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
 * Here's an example usage:
 *
 *     // Initialize a stream for the KeyEvents:
 *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
 *     // Start listening to the stream of KeyEvents.
 *     stream.listen((keyEvent) =>
 *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
 *     ...
 *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
 *     // listeners can know a KeyEvent happened.
 *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyEvent extends _WrappedEvent implements KeyboardEvent {
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Calculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Calculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Calculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => JS('int', '#.keyCode', _parent);

  /** Accessor to the underlying charCode value is the parent event. */
  int get _realCharCode => JS('int', '#.charCode', _parent);

  /** Accessor to the underlying altKey value is the parent event. */
  bool get _realAltKey => JS('bool', '#.altKey', _parent);

  /** Shadows on top of the parent's currentTarget. */
  EventTarget _currentTarget;

  final InputDeviceCapabilities sourceCapabilities;

  /**
   * The value we want to use for this object's dispatch. Created here so it is
   * only invoked once.
   */
  static final _keyboardEventDispatchRecord = _makeRecord();

  /** Helper to statically create the dispatch record. */
  static _makeRecord() {
    var interceptor = JS_INTERCEPTOR_CONSTANT(KeyboardEvent);
    return makeLeafDispatchRecord(interceptor);
  }

  /** Construct a KeyEvent with [parent] as the event we're emulating. */
  KeyEvent.wrap(KeyboardEvent parent) : super(parent) {
    _parent = parent;
    _shadowAltKey = _realAltKey;
    _shadowCharCode = _realCharCode;
    _shadowKeyCode = _realKeyCode;
    _currentTarget = _parent.currentTarget;
  }

  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
  factory KeyEvent(String type,
      {Window view,
      bool canBubble: true,
      bool cancelable: true,
      int keyCode: 0,
      int charCode: 0,
      int location: 1,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget currentTarget}) {
    if (view == null) {
      view = window;
    }

    var eventObj;

    // Currently this works on everything but Safari. Safari throws an
    // "Attempting to change access mechanism for an unconfigurable property"
    // TypeError when trying to do the Object.defineProperty hack, so we avoid
    // this branch if possible.
    // Also, if we want this branch to work in FF, we also need to modify
    // _initKeyboardEvent to also take charCode and keyCode values to
    // initialize initKeyEvent.

    eventObj = new Event.eventType('KeyboardEvent', type,
        canBubble: canBubble, cancelable: cancelable);

    // Chromium Hack
    JS(
        'void',
        "Object.defineProperty(#, 'keyCode', {"
        "  get : function() { return this.keyCodeVal; } })",
        eventObj);
    JS(
        'void',
        "Object.defineProperty(#, 'which', {"
        "  get : function() { return this.keyCodeVal; } })",
        eventObj);
    JS(
        'void',
        "Object.defineProperty(#, 'charCode', {"
        "  get : function() { return this.charCodeVal; } })",
        eventObj);

    var keyIdentifier = _convertToHexString(charCode, keyCode);
    eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
        keyIdentifier, location, ctrlKey, altKey, shiftKey, metaKey);
    JS('void', '#.keyCodeVal = #', eventObj, keyCode);
    JS('void', '#.charCodeVal = #', eventObj, charCode);

    // Tell dart2js that it smells like a KeyboardEvent!
    setDispatchProperty(eventObj, _keyboardEventDispatchRecord);

    var keyEvent = new KeyEvent.wrap(eventObj);
    if (keyEvent._currentTarget == null) {
      keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
    }
    return keyEvent;
  }

  // Currently known to work on all browsers but IE.
  static bool get canUseDispatchEvent => JS(
      'bool',
      '(typeof document.body.dispatchEvent == "function")'
      '&& document.body.dispatchEvent.length > 0');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  // This is an experimental method to be sure.
  static String _convertToHexString(int charCode, int keyCode) {
    if (charCode != -1) {
      var hex = charCode.toRadixString(16); // Convert to hexadecimal.
      StringBuffer sb = new StringBuffer('U+');
      for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
      sb.write(hex);
      return sb.toString();
    } else {
      return KeyCode._convertKeyCodeToKeyName(keyCode);
    }
  }

  // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
  // it the default keyboard event handling, move these methods over to Element.
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyDownEvent =
      new _KeyboardEventHandler('keydown');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyUpEvent =
      new _KeyboardEventHandler('keyup');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyPressEvent =
      new _KeyboardEventHandler('keypress');

  String get code => _parent.code;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  bool get isComposing => _parent.isComposing;
  String get key => _parent.key;
  /**
   * Accessor to the part of the keyboard that the key was pressed from (one of
   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
   */
  int get location => _parent.location;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(
      String type, bool canBubble, bool cancelable, Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }

  String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  int get _which => which;

  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }

  void _initKeyboardEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      String keyIdentifier,
      int location,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }

  bool getModifierState(String keyArgument) => throw new UnimplementedError();

  bool get repeat => throw new UnimplementedError();
  bool get isComposed => throw new UnimplementedError();
  dynamic get _get_view => throw new UnimplementedError();
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class Platform {
  /**
   * Returns true if dart:typed_data types are supported on this
   * browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsTypedData = JS('bool', '!!(window.ArrayBuffer)');

  /**
   * Returns true if SIMD types in dart:typed_data types are supported
   * on this browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsSimd = false;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Helper class to implement custom events which wrap DOM events.
 */
class _WrappedEvent implements Event {
  final Event wrapped;

  /** The CSS selector involved with event delegation. */
  String _selector;

  _WrappedEvent(this.wrapped);

  bool get bubbles => wrapped.bubbles;

  bool get cancelable => wrapped.cancelable;

  bool get composed => wrapped.composed;

  EventTarget get currentTarget => wrapped.currentTarget;

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  bool get isTrusted => wrapped.isTrusted;

  EventTarget get target => wrapped.target;

  double get timeStamp => wrapped.timeStamp;

  String get type => wrapped.type;

  void _initEvent(String type, [bool bubbles, bool cancelable]) {
    throw new UnsupportedError('Cannot initialize this Event.');
  }

  void preventDefault() {
    wrapped.preventDefault();
  }

  void stopImmediatePropagation() {
    wrapped.stopImmediatePropagation();
  }

  void stopPropagation() {
    wrapped.stopPropagation();
  }

  List<EventTarget> composedPath() => wrapped.composedPath();

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    Element currentTarget = this.currentTarget;
    Element target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to
   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
   *   from W3C.
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  List<Node> get path => wrapped.path;

  dynamic get _get_currentTarget => wrapped._get_currentTarget;

  dynamic get _get_target => wrapped._get_target;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

void Function(T) _wrapZone<T>(void Function(T) callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.root) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallbackGuarded(callback);
}

void Function(T1, T2) _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.root) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallbackGuarded(callback);
}

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
    document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {
  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {
  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);

  /**
   * A sanitizer for trees that we trust. It does no validation and allows
   * any elements. It is also more efficient, since it can pass the text
   * directly through to the underlying APIs without creating a document
   * fragment to be sanitized.
   */
  static const trusted = const _TrustedHtmlTreeSanitizer();
}

/**
 * A sanitizer for trees that we trust. It does no validation and allows
 * any elements.
 */
class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
  const _TrustedHtmlTreeSanitizer();

  sanitizeTree(Node node) {}
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
            _hiddenAnchor.port == _loc.port &&
            _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
            _hiddenAnchor.port == '' &&
            (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
  }
}

class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(Element._safeTagName(element));
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError(
          '${Element._safeTagName(element)}[$attributeName="$value"]');
    }
  }
}

/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node, Node parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (null != child) {
        var nextChild;
        try {
          // Child may be removed during the walk, and we may not
          // even be able to get its previousNode.
          nextChild = child.previousNode;
        } catch (e) {
          // Child appears bad, remove it. We want to check the rest of the
          // children of node and, but we have no way of getting to the next
          // child, so start again from the last child.
          _removeNode(child, node);
          child = null;
          nextChild = node.lastChild;
        }
        if (child != null) walk(child, node);
        child = nextChild;
      }
    }

    walk(node, null);
  }

  /// Aggressively try to remove node.
  void _removeNode(Node node, Node parent) {
    // If we have the parent, it's presumably already passed more sanitization
    // or is the fragment, so ask it to remove the child. And if that fails
    // try to set the outer html.
    if (parent == null) {
      node.remove();
    } else {
      parent._removeChild(node);
    }
  }

  /// Sanitize the element, assuming we can't trust anything about it.
  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
    // If the _hasCorruptedAttributes does not successfully return false,
    // then we consider it corrupted and remove.
    // TODO(alanknight): This is a workaround because on Firefox
    // embed/object
    // tags typeof is "function", not "object". We don't recognize them, and
    // can't call methods. This does mean that you can't explicitly allow an
    // embed tag. The only thing that will let it through is a null
    // sanitizer that doesn't traverse the tree at all. But sanitizing while
    // allowing embeds seems quite unlikely. This is also the reason that we
    // can't declare the type of element, as an embed won't pass any type
    // check in dart2js.
    var corrupted = true;
    var attrs;
    var isAttr;
    try {
      // If getting/indexing attributes throws, count that as corrupt.
      attrs = element.attributes;
      isAttr = attrs['is'];
      var corruptedTest1 = Element._hasCorruptedAttributes(element);

      // On IE, erratically, the hasCorruptedAttributes test can return false,
      // even though it clearly is corrupted. A separate copy of the test
      // inlining just the basic check seems to help.
      corrupted = corruptedTest1
          ? true
          : Element._hasCorruptedAttributesAdditionalCheck(element);
    } catch (e) {}
    var elementText = 'element unprintable';
    try {
      elementText = element.toString();
    } catch (e) {}
    try {
      var elementTagName = Element._safeTagName(element);
      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
          attrs, isAttr);
    } on ArgumentError {
      // Thrown by _ThrowsNodeValidator
      rethrow;
    } catch (e) {
      // Unexpected exception sanitizing -> remove
      _removeNode(element, parent);
      window.console.warn('Removing corrupted element $elementText');
    }
  }

  /// Having done basic sanity checking on the element, and computed the
  /// important attributes we want to check, remove it if it's not valid
  /// or not allowed, either as a whole or particular attributes.
  void _sanitizeElement(Element element, Node parent, bool corrupted,
      String text, String tag, Map attrs, String isAttr) {
    if (false != corrupted) {
      _removeNode(element, parent);
      window.console
          .warn('Removing element due to corrupted attributes on <$text>');
      return;
    }
    if (!validator.allowsElement(element)) {
      _removeNode(element, parent);
      window.console.warn('Removing disallowed element <$tag> from $parent');
      return;
    }

    if (isAttr != null) {
      if (!validator.allowsAttribute(element, 'is', isAttr)) {
        _removeNode(element, parent);
        window.console.warn('Removing disallowed type extension '
            '<$tag is="$isAttr">');
        return;
      }
    }

    // TODO(blois): Need to be able to get all attributes, irrespective of
    // XMLNS.
    var keys = attrs.keys.toList();
    for (var i = attrs.length - 1; i >= 0; --i) {
      var name = keys[i];
      if (!validator.allowsAttribute(
          element, name.toLowerCase(), attrs[name])) {
        window.console.warn('Removing disallowed attribute '
            '<$tag $name="${attrs[name]}">');
        attrs.remove(name);
      }
    }

    if (element is TemplateElement) {
      TemplateElement template = element;
      sanitizeTree(template.content);
    }
  }

  /// Sanitize the node and its children recursively.
  void sanitizeNode(Node node, Node parent) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        _sanitizeUntrustedElement(node, parent);
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        _removeNode(node, parent);
    }
  }
}
