library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
import "dart:_internal" as _in;

import "dart:async";

class Node extends core::Object {
  final field core::List<self::Node*>* nested;
  final field core::String* name;
  constructor •(core::String* name, [core::List<self::Node*>* nested = #C1]) → self::Node*
    : self::Node::name = name, self::Node::nested = nested, super core::Object::•() {}
  method toString() → core::String*
    return "<${this.{self::Node::name}{core::String*}}:[${let final core::List<self::Node*>* #t1 = this.{self::Node::nested}{core::List<self::Node*>*} in #t1 == null ?{core::String*} null : #t1.{core::Iterable::join}(", "){([core::String*]) →* core::String*}}]>";
  method toSimpleString() → dynamic {
    core::Iterable<dynamic>* tmp = let final core::List<self::Node*>* #t2 = this.{self::Node::nested}{core::List<self::Node*>*} in #t2 == null ?{core::Iterable<dynamic>*} null : #t2.{core::Iterable::map}<dynamic>((self::Node* child) → dynamic => child.{self::Node::toSimpleString}(){() →* dynamic}){((self::Node*) →* dynamic) →* core::Iterable<dynamic>*};
    return "${this.{self::Node::name}{core::String*}} ${let final core::Iterable<dynamic>* #t3 = tmp in #t3 == null ?{core::String*} null : #t3.{core::Iterable::join}(" "){([core::String*]) →* core::String*}}".{core::String::trim}(){() →* core::String*};
  }
  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
static method main() → void /* originally async */ {
  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
  core::bool* :is_sync = false;
  FutureOr<dynamic>* :return_value;
  (dynamic) →* dynamic :async_op_then;
  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
  core::int* :await_jump_var = 0;
  dynamic :await_ctx_var;
  dynamic :saved_try_context_var0;
  dynamic :async_temporary_0;
  dynamic :async_temporary_1;
  dynamic :async_temporary_2;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L1:
      {
        core::String* expected = "1 2 3 4 5 6 7 8 9 10";
        :async_temporary_2 = new self::Node::•("2", core::_GrowableList::•<self::Node*>(0));
        [yield] let dynamic #t4 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("7", core::_GrowableList::•<self::Node*>(0))), :async_op_then, :async_op_error, :async_op) in null;
        [yield] let dynamic #t5 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("6", core::_GrowableList::_literal1<self::Node*>(_in::unsafeCast<self::Node*>(:result)))), :async_op_then, :async_op_error, :async_op) in null;
        :async_temporary_1 = _in::unsafeCast<self::Node*>(:result);
        [yield] let dynamic #t6 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("8", core::_GrowableList::•<self::Node*>(0))), :async_op_then, :async_op_error, :async_op) in null;
        :async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
        [yield] let dynamic #t7 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("9", core::_GrowableList::•<self::Node*>(0))), :async_op_then, :async_op_error, :async_op) in null;
        [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("4", core::_GrowableList::_literal1<self::Node*>(new self::Node::•("5", core::_GrowableList::_literal3<self::Node*>(_in::unsafeCast<self::Node*>(:async_temporary_1), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)))))), :async_op_then, :async_op_error, :async_op) in null;
        [yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("3", core::_GrowableList::_literal1<self::Node*>(_in::unsafeCast<self::Node*>(:result)))), :async_op_then, :async_op_error, :async_op) in null;
        :async_temporary_0 = _in::unsafeCast<self::Node*>(:result);
        [yield] let dynamic #t10 = asy::_awaitHelper(asy::Future::value<self::Node*>(new self::Node::•("10", core::_GrowableList::•<self::Node*>(0))), :async_op_then, :async_op_error, :async_op) in null;
        self::Node* node = new self::Node::•("1", core::_GrowableList::_literal3<self::Node*>(_in::unsafeCast<self::Node*>(:async_temporary_2), _in::unsafeCast<self::Node*>(:async_temporary_0), _in::unsafeCast<self::Node*>(:result)));
        core::String* actual = node.{self::Node::toSimpleString}(){() →* dynamic} as{TypeError,ForDynamic} core::String*;
        core::print(actual);
        if(!(actual =={core::String::==}{(core::Object*) →* core::bool*} expected)) {
          throw "Expected '${expected}' but got '${actual}'";
        }
      }
      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
      return;
    }
    on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
    }
  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
  :async_op.call();
  :is_sync = true;
  return :async_future;
}

constants  {
  #C1 = null
}
