- label: 'I have one existing Observable, and'
  children:
    - label: I want to change each emitted value
      children:
        - label: to be a constant value
          children:
            - label: mapTo
        - label: to be a value calculated through a formula
          children:
            - label: map
    - label: I want to pick a property off each emitted value
      children:
        - label: pluck
    - label: I want to spy the values being emitted without affecting them
      children:
        - label: tap
    - label: I want to allow some values to pass
      children:
        - label: based on custom logic
          children:
            - label: filter
        - label: if they are at the start of the Observable
          children:
            - label: and only the first value
              children:
                - label: first
            - label: based on a given amount
              children:
                - label: take
            - label: based on custom logic
              children:
                - label: takeWhile
        - label: if they are exactly the n-th emission
          children:
            - label: elementAt
        - label: if they are at the end of the Observable
          children:
            - label: and only the last value
              children:
                - label: last
            - label: based on a given amount
              children:
                - label: takeLast
        - label: until another Observable emits a value
          children:
            - label: takeUntil
    - label: I want to ignore values
      children:
        - label: altogether
          children:
            - label: ignoreElements
        - label: from the start of the Observable
          children:
            - label: based on a given amount
              children:
                - label: skip
            - label: based on custom logic
              children:
                - label: skipWhile
        - label: from the end of the Observable
          children:
            - label: skipLast
        - label: until another Observable emits a value
          children:
            - label: skipUntil
        - label: that match some previous value
          children:
            - label: according to value equality
              children:
                - label: emitted just before the current value
                  children:
                    - label: distinctUntilChanged
                - label: emitted some time in the past
                  children:
                    - label: distinct
            - label: according to a key or object property
              children:
                - label: emitted just before the current value
                  children:
                    - label: distinctUntilKeyChanged
        - label: that occur too frequently
          children:
            - label: by emitting the first value in each time window
              children:
                - label: where time windows are determined by another Observable's emissions
                  children:
                    - label: throttle
                - label: where time windows are determined by a time duration
                  children:
                    - label: throttleTime
            - label: by emitting the last value in each time window
              children:
                - label: where time windows are determined by another Observable's emissions
                  children:
                    - label: audit
                - label: where time windows are determined by a time duration
                  children:
                    - label: auditTime
            - label: by emitting the last value as soon as enough silence has occurred
              children:
                - label: where the silence duration threshold is determined by another Observable
                  children:
                    - label: debounce
                - label: where the silence duration threshold is determined by a time duration
                  children:
                    - label: debounceTime
    - label: I want to compute a formula using all values emitted
      children:
        - label: and only output the final computed value
          children:
            - label: reduce
        - label: and output the computed values when the source emits a value
          children:
            - label: scan
        - label: and output the computed values as a nested Observable when the source emits a value
          children:
            - label: mergeScan
        - label: and output the computed values as a nested Observable when the source emits a value while unsubscribing from the previous nested Observable
          children:
            - label: switchScan
    - label: I want to wrap its messages with metadata
      children:
        - label: that describes each notification (next, error, or complete)
          children:
            - label: materialize
        - label: that includes the time past since the last emitted value
          children:
            - label: timeInterval
    - label: after a period of inactivity
      children:
        - label: I want to throw an error
          children:
            - label: timeout
        - label: I want to switch to another Observable
          children:
            - label: timeoutWith
    - label: I want to ensure there is only one value
      children:
        - label: single
    - label: I want to know how many values it emits
      children:
        - label: count
    - label: I want to prepend one value
      children:
        - label: startWith
    - label: I want to delay the emissions
      children:
        - label: based on a given amount of time
          children:
            - label: delay
        - label: based on the emissions of another Observable
          children:
            - label: delayWhen
    - label: I want to group the values
      children:
        - label: until the Observable completes
          children:
            - label: and convert to an array
              children:
                - label: toArray
            - label: and convert to a Promise
              children:
                - label: Observable
                  method: toPromise
        - label: consecutively in pairs, as arrays
          children:
            - label: pairwise
        - label: 'based on a criterion, and output two Observables: those that match the criterion and those that do not'
          children:
            - label: partition
        - label: in batches of a particular size
          children:
            - label: and emit the group as an array
              children:
                - label: bufferCount
            - label: and emit the group as a nested Observable
              children:
                - label: windowCount
        - label: based on time
          children:
            - label: and emit the group as an array
              children:
                - label: bufferTime
            - label: and emit the group as a nested Observable
              children:
                - label: windowTime
        - label: until another Observable emits
          children:
            - label: and emit the group as an array
              children:
                - label: buffer
            - label: and emit the group as a nested Observable
              children:
                - label: window
        - label: based on the emissions of an Observable created on-demand
          children:
            - label: and emit the group as an array
              children:
                - label: bufferWhen
            - label: and emit the group as a nested Observable
              children:
                - label: windowWhen
        - label: based on another Observable for opening a group, and an Observable for closing a group
          children:
            - label: and emit the group as an array
              children:
                - label: bufferToggle
            - label: and emit the group as a nested Observable
              children:
                - label: windowToggle
        - label: based on a key calculated from the emitted values
          children:
            - label: groupBy
    - label: I want to start a new Observable for each value
      children:
        - label: and emit the values from all nested Observables in parallel
          children:
            - label: where the nested Observable is the same for every value
              children:
                - label: mergeMapTo
            - label: where the nested Observable is calculated for each value
              children:
                - label: mergeMap
        - label: and emit the values from each nested Observable in order
          children:
            - label: where the nested Observable is the same for every value
              children:
                - label: concatMapTo
            - label: where the nested Observable is calculated for each value
              children:
                - label: concatMap
        - label: and cancel the previous nested Observable when a new value arrives
          children:
            - label: where the nested Observable is the same for every value
              children:
                - label: switchMapTo
            - label: where the nested Observable is calculated for each value
              children:
                - label: switchMap
        - label: and ignore incoming values while the current nested Observable has not yet completed
          children:
            - label: exhaustMap
        - label: and recursively start a new Observable for each new value
          children:
            - label: expand
    - label: I want to perform custom operations
      children:
        - label: pipe
    - label: I want to share a subscription between multiple subscribers
      children:
        - label: using a conventional Subject
          children:
            - label: and start it as soon as the first subscriber arrives
              children:
                - label: share
            - label: and start it manually or imperatively
              children:
                - label: publish
        - label: using a BehaviorSubject
          children:
            - label: publishBehavior
        - label: using a ReplaySubject
          children:
            - label: publishReplay
        - label: using an AsyncSubject
          children:
            - label: publishLast
        - label: using a specific subject implementation
          children:
            - label: multicast
    - label: when an error occurs
      children:
        - label: I want to start a new Observable
          children:
            - label: catchError
        - label: I want to re-subscribe
          children:
            - label: immediately
              children:
                - label: retry
            - label: when another Observable emits
              children:
                - label: retryWhen
    - label: when it completes
      children:
        - label: I want to re-subscribe
          children:
            - label: immediately
              children:
                - label: repeat
            - label: when another Observable emits
              children:
                - label: repeatWhen
        - label: I want to start a new Observable
          children:
            - label: concat
    - label: when it completes, errors or unsubscribes, I want to execute a function
      children:
        - label: finalize
    - label: I want to change the scheduler
      children:
        - label: that routes calls to subscribe
          children:
            - label: subscribeOn
        - label: that routes values to observers
          children:
            - label: observeOn
    - label: I want to combine this Observable with others, and
      children:
        - label: I want to receive values only from the Observable that emits a value first
          children:
            - label: race
        - label: I want to output the values from either of them
          children:
            - label: merge
        - label: I want to output a value computed from values of the source Observables
          children:
            - label: using the latest value of each source whenever any source emits
              children:
                - label: combineLatest
            - label: using the latest value of each source only when the primary Observable emits
              children:
                - label: withLatestFrom
            - label: using each source value only once
              children:
                - label: zip
- label: 'I have some Observables to combine together as one Observable, and'
  children:
    - label: I want to receive values only from the Observable that emits a value first
      children:
        - label: race
    - label: I want to be notified when all of them have completed
      children:
        - label: forkJoin
    - label: I want to output the values from either of them
      children:
        - label: merge
    - label: I want to output a value computed from values of the source Observables
      children:
        - label: using the latest value of each source whenever any source emits
          children:
            - label: combineLatest
        - label: using each source value only once
          children:
            - label: zip
    - label: I want to subscribe to each in order
      children:
        - label: concat
- label: 'I have no Observables yet, and'
  children:
    - label: I want to create a new Observable
      children:
        - label: using custom logic
          children:
            - label: Observable
              method: create
        - label: using a state machine similar to a for loop
          children:
            - label: generate
        - label: that throws an error
          children:
            - label: throwError
        - label: that just completes, without emitting values
          children:
            - label: EMPTY
        - label: that never emits anything
          children:
            - label: NEVER
        - label: from an existing source of events
          children:
            - label: coming from the DOM or Node.js or similar
              children:
                - label: fromEvent
            - label: that uses an API to add and remove event handlers
              children:
                - label: fromEventPattern
        - label: from a Promise or an event source
          children:
            - label: from
        - label: that iterates
          children:
            - label: over the values in an array
              children:
                - label: from
            - label: over values in a numeric range
              children:
                - label: range
            - label: over prefined values given as arguments
              children:
                - label: of
        - label: that emits values on a timer
          children:
            - label: regularly
              children:
                - label: interval
            - label: with an optional initial delay
              children:
                - label: timer
        - label: which is built on demand when subscribed
          children:
            - label: defer
    - label: I want to convert a callback to an Observable
      children:
        - label: supporting a conventional callback API
          children:
            - label: bindCallback
        - label: supporting Node.js callback style API
          children:
            - label: bindNodeCallback
