Repository: Reactive-Extensions/RxJS
Branch: master
Commit: 6770d24307ed
Files: 1749
Total size: 14.5 MB
Directory structure:
gitextract_8zo3mywg/
├── .coveralls.yml
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .jamignore
├── .jscsrc
├── .jscsrc.todo
├── .jshintrc
├── .npmignore
├── .nuget/
│ ├── nuget.config
│ └── nuget.targets
├── .travis.yml
├── Gruntfile.js
├── authors.txt
├── bower.json
├── code-of-conduct.md
├── component.json
├── contributing.md
├── dist/
│ ├── rx.aggregates.js
│ ├── rx.all.compat.js
│ ├── rx.all.js
│ ├── rx.async.compat.js
│ ├── rx.async.js
│ ├── rx.backpressure.js
│ ├── rx.binding.js
│ ├── rx.coincidence.js
│ ├── rx.compat.js
│ ├── rx.core.binding.js
│ ├── rx.core.js
│ ├── rx.core.testing.js
│ ├── rx.experimental.js
│ ├── rx.joinpatterns.js
│ ├── rx.js
│ ├── rx.lite.compat.js
│ ├── rx.lite.extras.compat.js
│ ├── rx.lite.extras.js
│ ├── rx.lite.js
│ ├── rx.sorting.js
│ ├── rx.testing.js
│ ├── rx.time.js
│ └── rx.virtualtime.js
├── doc/
│ ├── api/
│ │ ├── config/
│ │ │ └── readme.md
│ │ ├── core/
│ │ │ ├── notification.md
│ │ │ ├── observable.md
│ │ │ ├── observer.md
│ │ │ └── operators/
│ │ │ ├── amb.md
│ │ │ ├── ambproto.md
│ │ │ ├── and.md
│ │ │ ├── asobservable.md
│ │ │ ├── average.md
│ │ │ ├── buffer.md
│ │ │ ├── bufferwithcount.md
│ │ │ ├── bufferwithtime.md
│ │ │ ├── bufferwithtimeorcount.md
│ │ │ ├── case.md
│ │ │ ├── catch.md
│ │ │ ├── catchproto.md
│ │ │ ├── combinelatest.md
│ │ │ ├── combinelatestproto.md
│ │ │ ├── concat.md
│ │ │ ├── concatall.md
│ │ │ ├── concatmap.md
│ │ │ ├── concatmapobserver.md
│ │ │ ├── concatproto.md
│ │ │ ├── connect.md
│ │ │ ├── controlled.md
│ │ │ ├── count.md
│ │ │ ├── create.md
│ │ │ ├── debounce.md
│ │ │ ├── defaultifempty.md
│ │ │ ├── defer.md
│ │ │ ├── delay.md
│ │ │ ├── delaysubscription.md
│ │ │ ├── dematerialize.md
│ │ │ ├── distinct.md
│ │ │ ├── distinctuntilchanged.md
│ │ │ ├── do.md
│ │ │ ├── dooncompleted.md
│ │ │ ├── doonerror.md
│ │ │ ├── doonnext.md
│ │ │ ├── dowhile.md
│ │ │ ├── elementat.md
│ │ │ ├── empty.md
│ │ │ ├── every.md
│ │ │ ├── expand.md
│ │ │ ├── finally.md
│ │ │ ├── find.md
│ │ │ ├── findindex.md
│ │ │ ├── first.md
│ │ │ ├── flatmapfirst.md
│ │ │ ├── flatmaplatest.md
│ │ │ ├── flatmapobserver.md
│ │ │ ├── flatmapwithmaxconcurrent.md
│ │ │ ├── for.md
│ │ │ ├── forkjoin.md
│ │ │ ├── forkjoinproto.md
│ │ │ ├── from.md
│ │ │ ├── fromarray.md
│ │ │ ├── fromcallback.md
│ │ │ ├── fromevent.md
│ │ │ ├── fromeventpattern.md
│ │ │ ├── fromnodecallback.md
│ │ │ ├── frompromise.md
│ │ │ ├── generate.md
│ │ │ ├── generatewithabsolutetime.md
│ │ │ ├── generatewithrelativetime.md
│ │ │ ├── groupby.md
│ │ │ ├── groupbyuntil.md
│ │ │ ├── groupjoin.md
│ │ │ ├── if.md
│ │ │ ├── ignoreelements.md
│ │ │ ├── includes.md
│ │ │ ├── indexof.md
│ │ │ ├── interval.md
│ │ │ ├── isempty.md
│ │ │ ├── join.md
│ │ │ ├── jortsort.md
│ │ │ ├── jortsortuntil.md
│ │ │ ├── last.md
│ │ │ ├── lastindexof.md
│ │ │ ├── let.md
│ │ │ ├── manyselect.md
│ │ │ ├── materialize.md
│ │ │ ├── max.md
│ │ │ ├── maxby.md
│ │ │ ├── merge.md
│ │ │ ├── mergeall.md
│ │ │ ├── mergedelayerror.md
│ │ │ ├── mergeproto.md
│ │ │ ├── min.md
│ │ │ ├── minby.md
│ │ │ ├── multicast.md
│ │ │ ├── never.md
│ │ │ ├── observeon.md
│ │ │ ├── of.md
│ │ │ ├── ofarraychanges.md
│ │ │ ├── ofobjectchanges.md
│ │ │ ├── ofwithscheduler.md
│ │ │ ├── onerrorresumenext.md
│ │ │ ├── onerrorresumenextproto.md
│ │ │ ├── pairs.md
│ │ │ ├── pairwise.md
│ │ │ ├── partition.md
│ │ │ ├── pausable.md
│ │ │ ├── pausablebuffered.md
│ │ │ ├── pluck.md
│ │ │ ├── publish.md
│ │ │ ├── publishlast.md
│ │ │ ├── publishvalue.md
│ │ │ ├── range.md
│ │ │ ├── reduce.md
│ │ │ ├── refcount.md
│ │ │ ├── repeat.md
│ │ │ ├── repeatproto.md
│ │ │ ├── repeatwhen.md
│ │ │ ├── replay.md
│ │ │ ├── retry.md
│ │ │ ├── retrywhen.md
│ │ │ ├── return.md
│ │ │ ├── sample.md
│ │ │ ├── scan.md
│ │ │ ├── select.md
│ │ │ ├── selectmany.md
│ │ │ ├── sequenceequal.md
│ │ │ ├── share.md
│ │ │ ├── sharereplay.md
│ │ │ ├── sharevalue.md
│ │ │ ├── single.md
│ │ │ ├── singleinstance.md
│ │ │ ├── skip.md
│ │ │ ├── skiplast.md
│ │ │ ├── skiplastwithtime.md
│ │ │ ├── skipuntil.md
│ │ │ ├── skipuntilwithtime.md
│ │ │ ├── skipwhile.md
│ │ │ ├── slice.md
│ │ │ ├── some.md
│ │ │ ├── spawn.md
│ │ │ ├── start.md
│ │ │ ├── startasync.md
│ │ │ ├── startwith.md
│ │ │ ├── subscribe.md
│ │ │ ├── subscribeon.md
│ │ │ ├── subscribeoncompleted.md
│ │ │ ├── subscribeonerror.md
│ │ │ ├── subscribeonnext.md
│ │ │ ├── sum.md
│ │ │ ├── switch.md
│ │ │ ├── switchfirst.md
│ │ │ ├── take.md
│ │ │ ├── takelast.md
│ │ │ ├── takelastbuffer.md
│ │ │ ├── takelastbufferwithtime.md
│ │ │ ├── takelastwithtime.md
│ │ │ ├── takeuntil.md
│ │ │ ├── takeuntilwithtime.md
│ │ │ ├── takewhile.md
│ │ │ ├── thendo.md
│ │ │ ├── throttle.md
│ │ │ ├── throw.md
│ │ │ ├── timeinterval.md
│ │ │ ├── timeout.md
│ │ │ ├── timer.md
│ │ │ ├── timestamp.md
│ │ │ ├── toarray.md
│ │ │ ├── toasync.md
│ │ │ ├── tomap.md
│ │ │ ├── topromise.md
│ │ │ ├── toset.md
│ │ │ ├── transduce.md
│ │ │ ├── using.md
│ │ │ ├── when.md
│ │ │ ├── where.md
│ │ │ ├── while.md
│ │ │ ├── window.md
│ │ │ ├── windowwithcount.md
│ │ │ ├── windowwithtime.md
│ │ │ ├── windowwithtimeorcount.md
│ │ │ ├── withlatestfrom.md
│ │ │ ├── wrap.md
│ │ │ ├── zip.md
│ │ │ ├── zipiterable.md
│ │ │ └── zipproto.md
│ │ ├── disposables/
│ │ │ ├── compositedisposable.md
│ │ │ ├── disposable.md
│ │ │ ├── refcountdisposable.md
│ │ │ ├── serialdisposable.md
│ │ │ └── singleassignmentdisposable.md
│ │ ├── helpers/
│ │ │ └── readme.md
│ │ ├── schedulers/
│ │ │ ├── historicalscheduler.md
│ │ │ ├── scheduler.md
│ │ │ └── virtualtimescheduler.md
│ │ ├── subjects/
│ │ │ ├── asyncsubject.md
│ │ │ ├── behaviorsubject.md
│ │ │ ├── replaysubject.md
│ │ │ └── subject.md
│ │ └── testing/
│ │ ├── reactivetest.md
│ │ ├── recorded.md
│ │ ├── subscription.md
│ │ └── testscheduler.md
│ ├── designguidelines/
│ │ └── readme.md
│ ├── gettingstarted/
│ │ ├── backpressure.md
│ │ ├── callbacks.md
│ │ ├── categories.md
│ │ ├── combining.md
│ │ ├── creating.md
│ │ ├── creatingquerying.md
│ │ ├── errors.md
│ │ ├── events.md
│ │ ├── exploring.md
│ │ ├── generators.md
│ │ ├── operators.md
│ │ ├── promises.md
│ │ ├── querying.md
│ │ ├── schedulers.md
│ │ ├── subjects.md
│ │ ├── testing.md
│ │ ├── transducers.md
│ │ ├── what.md
│ │ ├── which-instance.md
│ │ └── which-static.md
│ ├── howdoi/
│ │ ├── angular.md
│ │ ├── createcustomoperators.md
│ │ ├── eventemitter.md
│ │ ├── jquery.md
│ │ └── wrap.md
│ ├── libraries/
│ │ ├── core/
│ │ │ ├── rx.core.binding.md
│ │ │ ├── rx.core.md
│ │ │ └── rx.core.testing.md
│ │ ├── lite/
│ │ │ ├── rx.lite.aggregates.md
│ │ │ ├── rx.lite.async.md
│ │ │ ├── rx.lite.coincidence.md
│ │ │ ├── rx.lite.experimental.md
│ │ │ ├── rx.lite.extras.md
│ │ │ ├── rx.lite.joinpatterns.md
│ │ │ ├── rx.lite.md
│ │ │ ├── rx.lite.testing.md
│ │ │ ├── rx.lite.time.md
│ │ │ └── rx.lite.virtualtime.md
│ │ └── main/
│ │ ├── rx.aggregates.md
│ │ ├── rx.async.md
│ │ ├── rx.backpressure.md
│ │ ├── rx.binding.md
│ │ ├── rx.coincidence.md
│ │ ├── rx.complete.md
│ │ ├── rx.experimental.md
│ │ ├── rx.joinpatterns.md
│ │ ├── rx.md
│ │ ├── rx.testing.md
│ │ ├── rx.time.md
│ │ └── rx.virtualtime.md
│ ├── mapping/
│ │ ├── async/
│ │ │ ├── comparing.md
│ │ │ └── whyrx.md
│ │ ├── bacon.js/
│ │ │ ├── comparing.md
│ │ │ └── whyrx.md
│ │ └── highland/
│ │ ├── comparing.md
│ │ └── whyrx.md
│ └── readme.md
├── examples/
│ ├── alphabetinvasion/
│ │ ├── alphabetinvasion.html
│ │ ├── alphabetinvasion.js
│ │ ├── main.css
│ │ └── readme.md
│ ├── animationtest/
│ │ ├── index.html
│ │ ├── index.js
│ │ └── readme.md
│ ├── assets/
│ │ ├── bootstrap/
│ │ │ ├── css/
│ │ │ │ ├── bootstrap-responsive.css
│ │ │ │ └── bootstrap.css
│ │ │ └── js/
│ │ │ └── bootstrap.js
│ │ └── d3/
│ │ ├── LICENSE
│ │ └── d3.js
│ ├── autocomplete/
│ │ ├── autocomplete.html
│ │ ├── autocomplete.js
│ │ └── readme.md
│ ├── backpressure/
│ │ ├── index.html
│ │ ├── index.js
│ │ └── readme.md
│ ├── canvaspaint/
│ │ ├── canvaspaint.css
│ │ ├── canvaspaint.html
│ │ ├── canvaspaint.js
│ │ ├── excanvas_src.js
│ │ └── readme.md
│ ├── community.md
│ ├── crop/
│ │ ├── crop.css
│ │ ├── crop.html
│ │ ├── crop.js
│ │ ├── images/
│ │ │ └── attribution.txt
│ │ ├── readme.md
│ │ └── requestanimationframescheduler.js
│ ├── d3/
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── readme.md
│ ├── databinding/
│ │ ├── binding.css
│ │ ├── binding.html
│ │ ├── binding.js
│ │ └── readme.md
│ ├── dragndrop/
│ │ ├── dragndrop.css
│ │ ├── dragndrop.html
│ │ ├── dragndrop.js
│ │ └── readme.md
│ ├── followthemouse/
│ │ ├── followthemouse.css
│ │ ├── followthemouse.html
│ │ ├── followthemouse.js
│ │ └── readme.md
│ ├── keyboard-shortcuts/
│ │ ├── app.js
│ │ ├── keyCodeMap.js
│ │ ├── keyboard-shortcuts.html
│ │ ├── keyboard-shortcuts.js
│ │ └── readme.md
│ ├── konamicode/
│ │ ├── konamicode.html
│ │ ├── konamicode.js
│ │ └── readme.md
│ ├── letterrcount/
│ │ ├── lettercount.css
│ │ ├── lettercount.html
│ │ ├── lettercount.js
│ │ └── readme.md
│ ├── longstacktraces/
│ │ ├── longstacktraces.html
│ │ └── readme.md
│ ├── mario/
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ ├── polyfills.js
│ │ └── readme.md
│ ├── pacman-unicode/
│ │ ├── index.html
│ │ ├── index.js
│ │ ├── main.css
│ │ ├── pacman.js
│ │ ├── readme.md
│ │ └── unicodetiles/
│ │ ├── input.js
│ │ ├── unicodetiles.css
│ │ ├── unicodetiles.js
│ │ ├── ut.CanvasRenderer.js
│ │ ├── ut.DOMRenderer.js
│ │ └── ut.WebGLRenderer.js
│ ├── presentations.md
│ ├── readme.md
│ ├── requirejs/
│ │ ├── js/
│ │ │ ├── app/
│ │ │ │ └── main.js
│ │ │ ├── app.js
│ │ │ └── lib/
│ │ │ └── require.js
│ │ ├── readme.md
│ │ └── require-example.html
│ ├── simpledatabinding/
│ │ ├── readme.md
│ │ ├── simpledatabinding.html
│ │ └── simpledatabinding.js
│ ├── speech/
│ │ ├── readme.md
│ │ ├── speech.html
│ │ └── speech.js
│ ├── stockserver/
│ │ ├── AAPL.csv
│ │ ├── AMZN.csv
│ │ ├── CSCO.csv
│ │ ├── DELL.csv
│ │ ├── EMC.csv
│ │ ├── F.csv
│ │ ├── GE.csv
│ │ ├── GOOG.csv
│ │ ├── HP.csv
│ │ ├── IBM.csv
│ │ ├── MSFT.csv
│ │ ├── ORCL.csv
│ │ ├── RHT.csv
│ │ ├── YHOO.csv
│ │ ├── fileserver.js
│ │ ├── index.js
│ │ └── readme.md
│ ├── tessel/
│ │ ├── blinky.js
│ │ └── readme.md
│ ├── testing/
│ │ ├── jasmine/
│ │ │ ├── SpecRunner.html
│ │ │ ├── lib/
│ │ │ │ └── jasmine-1.3.1/
│ │ │ │ ├── MIT.LICENSE
│ │ │ │ ├── jasmine-html.js
│ │ │ │ ├── jasmine.css
│ │ │ │ └── jasmine.js
│ │ │ └── spec/
│ │ │ ├── SelectSpec.js
│ │ │ └── SpecHelper.js
│ │ ├── nodejs/
│ │ │ ├── collectionassert.js
│ │ │ └── tests.js
│ │ ├── qunit/
│ │ │ ├── customassertions.js
│ │ │ ├── qunit.css
│ │ │ ├── qunit.js
│ │ │ ├── tests.html
│ │ │ └── tests.js
│ │ └── readme.md
│ ├── timeflies/
│ │ ├── readme.md
│ │ ├── timeflies.css
│ │ ├── timeflies.html
│ │ └── timeflies.js
│ ├── videos.md
│ ├── worzone/
│ │ ├── asciigraphic.js
│ │ ├── audio/
│ │ │ ├── explosion.ogg
│ │ │ ├── fire.ogg
│ │ │ ├── intro1.ogg
│ │ │ ├── intro2.ogg
│ │ │ ├── join1.ogg
│ │ │ ├── join2.ogg
│ │ │ ├── move1.ogg
│ │ │ ├── move2.ogg
│ │ │ └── move3.ogg
│ │ ├── audio.js
│ │ ├── figureimage.js
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ ├── keyboard.js
│ │ ├── lib/
│ │ │ └── raphael-min.js
│ │ ├── maze.js
│ │ ├── readme.md
│ │ ├── rectangle.js
│ │ ├── rx.dom.lite.js
│ │ └── vector.js
│ └── wsh/
│ ├── example1.js
│ └── readme.md
├── index.js
├── lib/
│ ├── anonymousobserver.js
│ ├── anonymoussafeobserver.js
│ ├── concurrency/
│ │ ├── queuescheduler.js
│ │ └── scheduler.js
│ ├── disposables/
│ │ ├── binarydisposable.js
│ │ ├── compositedisposable.js
│ │ ├── disposable.js
│ │ └── singleassignmentdisposable.js
│ ├── internal/
│ │ ├── errors.js
│ │ ├── isfunction.js
│ │ ├── noop.js
│ │ ├── priorityqueue.js
│ │ ├── producer.js
│ │ ├── safeobserver.js
│ │ ├── sink.js
│ │ └── throwerror.js
│ ├── observable.js
│ ├── observablebase.js
│ └── observerbase.js
├── license.txt
├── modules/
│ ├── publish.js
│ ├── rx-core/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.core.js
│ ├── rx-core-binding/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.core.binding.js
│ ├── rx-core-testing/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.core.testing.js
│ ├── rx-lite/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.js
│ ├── rx-lite-aggregates/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.aggregates.js
│ ├── rx-lite-aggregates-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.aggregates.compat.js
│ ├── rx-lite-async/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.async.js
│ ├── rx-lite-async-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.async.compat.js
│ ├── rx-lite-backpressure/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.backpressure.js
│ ├── rx-lite-backpressure-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.backpressure.compat.js
│ ├── rx-lite-coincidence/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.coincidence.js
│ ├── rx-lite-coincidence-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.coincidence.compat.js
│ ├── rx-lite-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.compat.js
│ ├── rx-lite-experimental/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.experimental.js
│ ├── rx-lite-experimental-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.experimental.compat.js
│ ├── rx-lite-extras/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.extras.js
│ ├── rx-lite-extras-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.extras.compat.js
│ ├── rx-lite-joinpatterns/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.joinpatterns.js
│ ├── rx-lite-joinpatterns-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.joinpatterns.compat.js
│ ├── rx-lite-testing/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.testing.js
│ ├── rx-lite-testing-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.testing.compat.js
│ ├── rx-lite-time/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.time.js
│ ├── rx-lite-time-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.time.compat.js
│ ├── rx-lite-virtualtime/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.virtualtime.js
│ ├── rx-lite-virtualtime-compat/
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── rx.lite.virtualtime.compat.js
│ └── version.js
├── nuget/
│ ├── RxJS-Aggregates/
│ │ └── RxJS-Aggregates.nuspec
│ ├── RxJS-All/
│ │ └── RxJS-All.nuspec
│ ├── RxJS-Async/
│ │ └── RxJS-Async.nuspec
│ ├── RxJS-BackPressure/
│ │ └── RxJS-BackPressure.nuspec
│ ├── RxJS-Binding/
│ │ └── RxJS-Binding.nuspec
│ ├── RxJS-Coincidence/
│ │ └── RxJS-Coincidence.nuspec
│ ├── RxJS-Complete/
│ │ └── RxJS-Complete.nuspec
│ ├── RxJS-Experimental/
│ │ └── RxJS-Experimental.nuspec
│ ├── RxJS-JoinPatterns/
│ │ └── RxJS-JoinPatterns.nuspec
│ ├── RxJS-Lite/
│ │ └── RxJS-Lite.nuspec
│ ├── RxJS-Main/
│ │ └── RxJS-Main.nuspec
│ ├── RxJS-Testing/
│ │ └── RxJS-Testing.nuspec
│ ├── RxJS-Time/
│ │ └── RxJS-Time.nuspec
│ └── RxJS-VirtualTime/
│ └── RxJS-VirtualTime.nuspec
├── package.json
├── readme.md
├── src/
│ ├── core/
│ │ ├── abstractobserver.js
│ │ ├── anonymousobservable.js
│ │ ├── anonymousobserver.js
│ │ ├── autodetachobserver.js
│ │ ├── backpressure/
│ │ │ ├── controlled.js
│ │ │ ├── pausable.js
│ │ │ ├── pausablebuffered.js
│ │ │ ├── pauser.js
│ │ │ ├── stopandwait.js
│ │ │ └── windowed.js
│ │ ├── checkedobserver.js
│ │ ├── concurrency/
│ │ │ ├── catchscheduler.js
│ │ │ ├── currentthreadscheduler.js
│ │ │ ├── defaultscheduler.js
│ │ │ ├── historicalscheduler.js
│ │ │ ├── immediatescheduler.js
│ │ │ ├── scheduleditem.js
│ │ │ ├── scheduleperiodicrecursive.js
│ │ │ ├── scheduler.js
│ │ │ ├── scheduler.periodic.js
│ │ │ ├── scheduler.recursive.js
│ │ │ ├── scheduler.wrappers.js
│ │ │ └── virtualtimescheduler.js
│ │ ├── disposables/
│ │ │ ├── binarydisposable.js
│ │ │ ├── booleandisposable.js
│ │ │ ├── compositedisposable.js
│ │ │ ├── disposable.js
│ │ │ ├── refcountdisposable.js
│ │ │ └── scheduleddisposable.js
│ │ ├── enumerable.js
│ │ ├── expressions/
│ │ │ ├── ExpressionTrees.csproj
│ │ │ ├── ExpressionTrees.csproj.user
│ │ │ ├── ExpressionTrees.sln
│ │ │ ├── app.css
│ │ │ ├── app.js
│ │ │ ├── app.ts
│ │ │ ├── compiler.js
│ │ │ ├── compiler.ts
│ │ │ ├── index.html
│ │ │ ├── web.Debug.config
│ │ │ ├── web.Release.config
│ │ │ └── web.config
│ │ ├── headers/
│ │ │ ├── aggregatesheader.js
│ │ │ ├── asyncheader.js
│ │ │ ├── asyncintro.js
│ │ │ ├── backpressureheader.js
│ │ │ ├── basicheader-compat.js
│ │ │ ├── basicheader.js
│ │ │ ├── bindingheader.js
│ │ │ ├── coincidenceheader.js
│ │ │ ├── core-bindingheader.js
│ │ │ ├── core-intro.js
│ │ │ ├── core-testheader.js
│ │ │ ├── coreheader.js
│ │ │ ├── enumeratorheader.js
│ │ │ ├── experimentalheader.js
│ │ │ ├── exports.js
│ │ │ ├── intro.js
│ │ │ ├── joinpatternsheader.js
│ │ │ ├── license.js
│ │ │ ├── liteextrasheader.js
│ │ │ ├── liteheader-compat.js
│ │ │ ├── liteheader.js
│ │ │ ├── liteintro-compat.js
│ │ │ ├── liteintro.js
│ │ │ ├── litetestintro-compat.js
│ │ │ ├── litetestintro.js
│ │ │ ├── outro.js
│ │ │ ├── sortingheader.js
│ │ │ ├── subintro.js
│ │ │ ├── suboutro.js
│ │ │ ├── testheader.js
│ │ │ ├── testintro.js
│ │ │ ├── timeheader.js
│ │ │ └── virtualtimeheader.js
│ │ ├── internal/
│ │ │ ├── bindcallback.js
│ │ │ ├── dontenums.js
│ │ │ ├── errors.js
│ │ │ ├── isequal.js
│ │ │ ├── map.js
│ │ │ ├── polyfills.js
│ │ │ ├── priorityqueue.js
│ │ │ ├── trycatch.js
│ │ │ └── util.js
│ │ ├── joins/
│ │ │ ├── activeplan.js
│ │ │ ├── joinobserver.js
│ │ │ ├── pattern.js
│ │ │ └── plan.js
│ │ ├── linq/
│ │ │ ├── connectableobservable.js
│ │ │ ├── enumerable/
│ │ │ │ └── while.js
│ │ │ ├── groupedobservable.js
│ │ │ └── observable/
│ │ │ ├── _extremaby.js
│ │ │ ├── _findvalue.js
│ │ │ ├── _firstonly.js
│ │ │ ├── _observabletimer.js
│ │ │ ├── _observabletimerdateandperiod.js
│ │ │ ├── _observabletimertimespanandperiod.js
│ │ │ ├── amb.js
│ │ │ ├── ambproto.js
│ │ │ ├── and.js
│ │ │ ├── asobservable.js
│ │ │ ├── average.js
│ │ │ ├── buffer.js
│ │ │ ├── bufferwithcount.js
│ │ │ ├── bufferwithtime.js
│ │ │ ├── bufferwithtimeorcount.js
│ │ │ ├── case.js
│ │ │ ├── catch.js
│ │ │ ├── catchproto.js
│ │ │ ├── combinelatestproto.js
│ │ │ ├── concatall.js
│ │ │ ├── concatmap.js
│ │ │ ├── concatmapobserver.js
│ │ │ ├── concatproto.js
│ │ │ ├── count.js
│ │ │ ├── create.js
│ │ │ ├── debounce.js
│ │ │ ├── defaultifempty.js
│ │ │ ├── defer.js
│ │ │ ├── delay.js
│ │ │ ├── delaysubscription.js
│ │ │ ├── dematerialize.js
│ │ │ ├── distinct.js
│ │ │ ├── dowhile.js
│ │ │ ├── elementat.js
│ │ │ ├── every.js
│ │ │ ├── expand.js
│ │ │ ├── find.js
│ │ │ ├── findindex.js
│ │ │ ├── first.js
│ │ │ ├── for.js
│ │ │ ├── forkjoin.js
│ │ │ ├── forkjoinproto.js
│ │ │ ├── fromevent.js
│ │ │ ├── fromeventpattern.js
│ │ │ ├── generate.js
│ │ │ ├── generatewithabsolutetime.js
│ │ │ ├── generatewithrelativetime.js
│ │ │ ├── groupby.js
│ │ │ ├── groupbyuntil.js
│ │ │ ├── groupjoin.js
│ │ │ ├── if.js
│ │ │ ├── includes.js
│ │ │ ├── indexof.js
│ │ │ ├── interval.js
│ │ │ ├── isempty.js
│ │ │ ├── join.js
│ │ │ ├── jortsort.js
│ │ │ ├── jortsortuntil.js
│ │ │ ├── last.js
│ │ │ ├── lastindexof.js
│ │ │ ├── let.js
│ │ │ ├── manyselect.js
│ │ │ ├── materialize.js
│ │ │ ├── max.js
│ │ │ ├── maxby.js
│ │ │ ├── merge.js
│ │ │ ├── mergedelayerror.js
│ │ │ ├── min.js
│ │ │ ├── minby.js
│ │ │ ├── multicast.js
│ │ │ ├── observeon.js
│ │ │ ├── ofarraychanges.js
│ │ │ ├── ofobjectchanges.js
│ │ │ ├── onerrorresumenext.js
│ │ │ ├── onerrorresumenextproto.js
│ │ │ ├── pairwise.js
│ │ │ ├── partition.js
│ │ │ ├── pipe.js
│ │ │ ├── pluck.js
│ │ │ ├── publish.js
│ │ │ ├── publishlast.js
│ │ │ ├── publishvalue.js
│ │ │ ├── repeatproto.js
│ │ │ ├── repeatwhen.js
│ │ │ ├── replay.js
│ │ │ ├── retry.js
│ │ │ ├── retrywhen.js
│ │ │ ├── sample.js
│ │ │ ├── selectmanyobserver.js
│ │ │ ├── sequenceequal.js
│ │ │ ├── share.js
│ │ │ ├── sharereplay.js
│ │ │ ├── sharevalue.js
│ │ │ ├── single.js
│ │ │ ├── singleinstance.js
│ │ │ ├── skiplast.js
│ │ │ ├── skiplastwithtime.js
│ │ │ ├── skipuntilwithtime.js
│ │ │ ├── skipwhile.js
│ │ │ ├── skipwithtime.js
│ │ │ ├── slice.js
│ │ │ ├── some.js
│ │ │ ├── spawn.js
│ │ │ ├── start.js
│ │ │ ├── startasync.js
│ │ │ ├── startwith.js
│ │ │ ├── subscribeon.js
│ │ │ ├── sum.js
│ │ │ ├── switchfirst.js
│ │ │ ├── takelast.js
│ │ │ ├── takelastbuffer.js
│ │ │ ├── takelastbufferwithtime.js
│ │ │ ├── takelastwithtime.js
│ │ │ ├── takeuntilwithtime.js
│ │ │ ├── takewhile.js
│ │ │ ├── takewithtime.js
│ │ │ ├── thendo.js
│ │ │ ├── throttle.js
│ │ │ ├── timeinterval.js
│ │ │ ├── timeout.js
│ │ │ ├── timer.js
│ │ │ ├── timestamp.js
│ │ │ ├── toasync.js
│ │ │ ├── tomap.js
│ │ │ ├── topromise.js
│ │ │ ├── toset.js
│ │ │ ├── transduce.js
│ │ │ ├── using.js
│ │ │ ├── when.js
│ │ │ ├── while.js
│ │ │ ├── window.js
│ │ │ ├── windowwithcount.js
│ │ │ ├── windowwithtime.js
│ │ │ ├── windowwithtimeorcount.js
│ │ │ ├── zip.js
│ │ │ └── zipiterable.js
│ │ ├── longstacktraces/
│ │ │ ├── longstackbegin.js
│ │ │ ├── longstackend.js
│ │ │ └── longstacktraces.js
│ │ ├── notification.js
│ │ ├── observable.js
│ │ ├── observeonobserver.js
│ │ ├── observer-extras.js
│ │ ├── observer-lite.js
│ │ ├── observer.js
│ │ ├── perf/
│ │ │ ├── observablebase.js
│ │ │ └── operators/
│ │ │ ├── combinelatest.js
│ │ │ ├── concat.js
│ │ │ ├── concatmap.js
│ │ │ ├── distinctuntilchanged.js
│ │ │ ├── empty.js
│ │ │ ├── filter.js
│ │ │ ├── finally.js
│ │ │ ├── flatmap.js
│ │ │ ├── flatmapbase.js
│ │ │ ├── flatmapfirst.js
│ │ │ ├── flatmaplatest.js
│ │ │ ├── flatmapwithmaxconcurrent.js
│ │ │ ├── from.js
│ │ │ ├── fromarray.js
│ │ │ ├── fromarrayobservable.js
│ │ │ ├── fromcallback.js
│ │ │ ├── fromnodecallback.js
│ │ │ ├── frompromise.js
│ │ │ ├── ignoreelements.js
│ │ │ ├── just.js
│ │ │ ├── map.js
│ │ │ ├── mergeall.js
│ │ │ ├── mergeconcat.js
│ │ │ ├── never.js
│ │ │ ├── of.js
│ │ │ ├── pairs.js
│ │ │ ├── range.js
│ │ │ ├── reduce.js
│ │ │ ├── repeat.js
│ │ │ ├── scan.js
│ │ │ ├── skip.js
│ │ │ ├── skipuntil.js
│ │ │ ├── switch.js
│ │ │ ├── take.js
│ │ │ ├── takeuntil.js
│ │ │ ├── tap.js
│ │ │ ├── throw.js
│ │ │ ├── toarray.js
│ │ │ ├── withlatestfrom.js
│ │ │ └── zip.js
│ │ ├── scheduledobserver.js
│ │ ├── subjects/
│ │ │ ├── anonymoussubject.js
│ │ │ ├── asyncsubject.js
│ │ │ ├── behaviorsubject.js
│ │ │ ├── innersubscription.js
│ │ │ ├── replaysubject.js
│ │ │ └── subject.js
│ │ └── testing/
│ │ ├── coldobservable.js
│ │ ├── hotobservable.js
│ │ ├── mockdisposable.js
│ │ ├── mockobserver.js
│ │ ├── mockpromise.js
│ │ ├── reactivetest.js
│ │ ├── recorded.js
│ │ ├── subscription.js
│ │ └── testscheduler.js
│ └── modular/
│ ├── asyncsubject.js
│ ├── behaviorsubject.js
│ ├── binarydisposable.js
│ ├── compositedisposable.js
│ ├── disposable.js
│ ├── dist/
│ │ ├── rx.all.js
│ │ └── rx.lite.js
│ ├── helpers/
│ │ ├── comparer.js
│ │ ├── identity.js
│ │ ├── isarraylike.js
│ │ ├── isfunction.js
│ │ ├── isiterable.js
│ │ ├── ispromise.js
│ │ ├── iterator.js
│ │ └── noop.js
│ ├── index.js
│ ├── internal/
│ │ ├── addproperties.js
│ │ ├── addref.js
│ │ ├── bindcallback.js
│ │ ├── clonearray.js
│ │ ├── errors.js
│ │ ├── innersubscription.js
│ │ ├── isequal.js
│ │ ├── priorityqueue.js
│ │ └── trycatchutils.js
│ ├── joins/
│ │ ├── activeplan.js
│ │ ├── joinobserver.js
│ │ ├── pattern.js
│ │ └── plan.js
│ ├── narydisposable.js
│ ├── notification.js
│ ├── observable/
│ │ ├── _extremabyobservable.js
│ │ ├── _findvalueobservable.js
│ │ ├── _firstonly.js
│ │ ├── and.js
│ │ ├── anonymousobservable.js
│ │ ├── asobservable.js
│ │ ├── average.js
│ │ ├── bindcallback.js
│ │ ├── bindnodecallback.js
│ │ ├── buffer.js
│ │ ├── buffercount.js
│ │ ├── buffertime.js
│ │ ├── buffertimeorcount.js
│ │ ├── case.js
│ │ ├── catch.js
│ │ ├── catchhandler.js
│ │ ├── combinelatest.js
│ │ ├── concat.js
│ │ ├── concatall.js
│ │ ├── connectableobservable.js
│ │ ├── controlled.js
│ │ ├── count.js
│ │ ├── create.js
│ │ ├── debounce.js
│ │ ├── defaultifempty.js
│ │ ├── defer.js
│ │ ├── delay.js
│ │ ├── delaysubscription.js
│ │ ├── dematerialize.js
│ │ ├── distinct.js
│ │ ├── distinctuntilchanged.js
│ │ ├── empty.js
│ │ ├── every.js
│ │ ├── filter.js
│ │ ├── finally.js
│ │ ├── find.js
│ │ ├── findindex.js
│ │ ├── first.js
│ │ ├── flatmap.js
│ │ ├── flatmapfirst.js
│ │ ├── flatmaplatest.js
│ │ ├── flatmapmaxconcurrent.js
│ │ ├── flatmapobservable.js
│ │ ├── forkjoin.js
│ │ ├── from.js
│ │ ├── fromarray.js
│ │ ├── fromevent.js
│ │ ├── fromeventpattern.js
│ │ ├── frompromise.js
│ │ ├── generate.js
│ │ ├── generateabsolute.js
│ │ ├── generaterelative.js
│ │ ├── groupjoin.js
│ │ ├── ignoreelements.js
│ │ ├── includes.js
│ │ ├── indexof.js
│ │ ├── interval.js
│ │ ├── isempty.js
│ │ ├── join.js
│ │ ├── just.js
│ │ ├── last.js
│ │ ├── lastindexof.js
│ │ ├── map.js
│ │ ├── materialize.js
│ │ ├── max.js
│ │ ├── maxby.js
│ │ ├── merge.js
│ │ ├── mergeall.js
│ │ ├── mergeconcat.js
│ │ ├── mergedelayerror.js
│ │ ├── min.js
│ │ ├── minby.js
│ │ ├── multicast.js
│ │ ├── never.js
│ │ ├── observablebase.js
│ │ ├── observeon.js
│ │ ├── of.js
│ │ ├── ofscheduled.js
│ │ ├── onerrorresumenext.js
│ │ ├── pairs.js
│ │ ├── pairwise.js
│ │ ├── partition.js
│ │ ├── pausable.js
│ │ ├── pausablebuffered.js
│ │ ├── pluck.js
│ │ ├── publish.js
│ │ ├── publishlast.js
│ │ ├── publishvalue.js
│ │ ├── race.js
│ │ ├── range.js
│ │ ├── reduce.js
│ │ ├── repeat.js
│ │ ├── repeatvalue.js
│ │ ├── repeatwhen.js
│ │ ├── replay.js
│ │ ├── retry.js
│ │ ├── retrywhen.js
│ │ ├── sample.js
│ │ ├── scan.js
│ │ ├── sequenceequal.js
│ │ ├── share.js
│ │ ├── sharereplay.js
│ │ ├── sharevalue.js
│ │ ├── skip.js
│ │ ├── skiplast.js
│ │ ├── skiplastwithtime.js
│ │ ├── skipuntil.js
│ │ ├── skipuntilwithtime.js
│ │ ├── skipwhile.js
│ │ ├── skipwithtime.js
│ │ ├── slice.js
│ │ ├── some.js
│ │ ├── start.js
│ │ ├── startasync.js
│ │ ├── startwith.js
│ │ ├── stopandwait.js
│ │ ├── subscribeon.js
│ │ ├── sum.js
│ │ ├── switch.js
│ │ ├── switchfirst.js
│ │ ├── take.js
│ │ ├── takelast.js
│ │ ├── takelastbuffer.js
│ │ ├── takelastbufferwithtime.js
│ │ ├── takelastwithtime.js
│ │ ├── takeuntil.js
│ │ ├── takeuntilwithtime.js
│ │ ├── takewhile.js
│ │ ├── tap.js
│ │ ├── thendo.js
│ │ ├── throttle.js
│ │ ├── throw.js
│ │ ├── timeinterval.js
│ │ ├── timer.js
│ │ ├── timestamp.js
│ │ ├── toarray.js
│ │ ├── toasync.js
│ │ ├── tomap.js
│ │ ├── topromise.js
│ │ ├── toset.js
│ │ ├── transduce.js
│ │ ├── using.js
│ │ ├── when.js
│ │ ├── window.js
│ │ ├── windowcount.js
│ │ ├── windowed.js
│ │ ├── windowtime.js
│ │ ├── windowtimeorcount.js
│ │ ├── withlatestfrom.js
│ │ ├── zip.js
│ │ └── zipiterable.js
│ ├── observable.js
│ ├── observer/
│ │ ├── abstractobserver.js
│ │ ├── anonymousobserver.js
│ │ ├── asobserver.js
│ │ ├── autodetachobserver.js
│ │ ├── checked.js
│ │ ├── checkedobserver.js
│ │ ├── create.js
│ │ ├── fromnotifier.js
│ │ ├── makesafe.js
│ │ ├── notifyon.js
│ │ ├── observeonobserver.js
│ │ ├── scheduledobserver.js
│ │ └── tonotifier.js
│ ├── observer.js
│ ├── package.json
│ ├── readme.md
│ ├── refcountdisposable.js
│ ├── replaysubject.js
│ ├── rx.lite.js
│ ├── scheduleddisposable.js
│ ├── scheduler/
│ │ ├── catchscheduler.js
│ │ ├── currentthreadscheduler.js
│ │ ├── defaultscheduler.js
│ │ ├── historicalscheduler.js
│ │ ├── immediatescheduler.js
│ │ ├── scheduleditem.js
│ │ ├── scheduleperiodicrecursive.js
│ │ └── virtualtimescheduler.js
│ ├── scheduler.js
│ ├── serialdisposable.js
│ ├── singleassignmentdisposable.js
│ ├── subject/
│ │ └── create.js
│ ├── subject.js
│ ├── test/
│ │ ├── asyncsubject.js
│ │ ├── average.js
│ │ ├── behaviorsubject.js
│ │ ├── binarydisposable.js
│ │ ├── bindcallback.js
│ │ ├── bindnodecallback.js
│ │ ├── buffer.js
│ │ ├── buffercount.js
│ │ ├── buffertime.js
│ │ ├── buffertimeorcount.js
│ │ ├── case.js
│ │ ├── catch.js
│ │ ├── catchhandler.js
│ │ ├── combinelatest.js
│ │ ├── compositedisposable.js
│ │ ├── concat.js
│ │ ├── connectableobservable.js
│ │ ├── controlled.js
│ │ ├── count.js
│ │ ├── create.js
│ │ ├── currentthreadscheduler.js
│ │ ├── debounce.js
│ │ ├── defaultifempty.js
│ │ ├── defaultscheduler.js
│ │ ├── defer.js
│ │ ├── delay.js
│ │ ├── delaysubscription.js
│ │ ├── disposable.js
│ │ ├── distinct.js
│ │ ├── distinctuntilchanged.js
│ │ ├── empty.js
│ │ ├── every.js
│ │ ├── filter.js
│ │ ├── finally.js
│ │ ├── find.js
│ │ ├── findindex.js
│ │ ├── first.js
│ │ ├── flatmap.js
│ │ ├── forkjoin.js
│ │ ├── from.js
│ │ ├── fromarray.js
│ │ ├── fromevent.js
│ │ ├── fromeventpattern.js
│ │ ├── frompromise.js
│ │ ├── generate.js
│ │ ├── generateabsolute.js
│ │ ├── generaterelative.js
│ │ ├── groupjoin.js
│ │ ├── historicalscheduler.js
│ │ ├── ignoreelements.js
│ │ ├── includes.js
│ │ ├── indexof.js
│ │ ├── interval.js
│ │ ├── isempty.js
│ │ ├── isequal.js
│ │ ├── join.js
│ │ ├── just.js
│ │ ├── last.js
│ │ ├── lastindexof.js
│ │ ├── map.js
│ │ ├── materialize.js
│ │ ├── max.js
│ │ ├── maxby.js
│ │ ├── merge.js
│ │ ├── mergeall.js
│ │ ├── mergeconcat.js
│ │ ├── mergedelayerror.js
│ │ ├── min.js
│ │ ├── minby.js
│ │ ├── multicast.js
│ │ ├── narydisposable.js
│ │ ├── never.js
│ │ ├── notification.js
│ │ ├── observeon.js
│ │ ├── observer.js
│ │ ├── of.js
│ │ ├── onerrorresumenext.js
│ │ ├── pairs.js
│ │ ├── pairwise.js
│ │ ├── partition.js
│ │ ├── pausable.js
│ │ ├── pausablebuffered.js
│ │ ├── pluck.js
│ │ ├── publish.js
│ │ ├── publishlast.js
│ │ ├── publishvalue.js
│ │ ├── race.js
│ │ ├── range.js
│ │ ├── reduce.js
│ │ ├── refcountdisposable.js
│ │ ├── repeat.js
│ │ ├── repeatwhen.js
│ │ ├── replay.js
│ │ ├── replaysubject.js
│ │ ├── retry.js
│ │ ├── retrywhen.js
│ │ ├── sample.js
│ │ ├── scan.js
│ │ ├── scheduler.js
│ │ ├── sequenceequal.js
│ │ ├── serialdisposable.js
│ │ ├── singleassignmentdisposable.js
│ │ ├── skip.js
│ │ ├── skiplast.js
│ │ ├── skiplastwithtime.js
│ │ ├── skipuntil.js
│ │ ├── skipuntilwithtime.js
│ │ ├── skipwhile.js
│ │ ├── skipwithtime.js
│ │ ├── slice.js
│ │ ├── some.js
│ │ ├── start.js
│ │ ├── startwith.js
│ │ ├── stopandwait.js
│ │ ├── subject.js
│ │ ├── subscribeon.js
│ │ ├── sum.js
│ │ ├── switch.js
│ │ ├── switchfirst.js
│ │ ├── take.js
│ │ ├── takelast.js
│ │ ├── takelastbuffer.js
│ │ ├── takelastbufferwithtime.js
│ │ ├── takelastwithtime.js
│ │ ├── takeuntil.js
│ │ ├── takeuntilwithtime.js
│ │ ├── takewhile.js
│ │ ├── tap.js
│ │ ├── throttle.js
│ │ ├── throw.js
│ │ ├── timeinterval.js
│ │ ├── timer.js
│ │ ├── timestamp.js
│ │ ├── toarray.js
│ │ ├── toasync.js
│ │ ├── tomap.js
│ │ ├── topromise.js
│ │ ├── toset.js
│ │ ├── transduce.js
│ │ ├── using.js
│ │ ├── when.js
│ │ ├── window.js
│ │ ├── windowcount.js
│ │ ├── windowed.js
│ │ ├── windowtime.js
│ │ ├── windowtimeorcount.js
│ │ ├── withlatestfrom.js
│ │ └── zip.js
│ ├── testing/
│ │ ├── coldobservable.js
│ │ ├── hotobservable.js
│ │ ├── mockdisposable.js
│ │ ├── mockobserver.js
│ │ ├── mockpromise.js
│ │ ├── reactiveassert.js
│ │ ├── reactivetest.js
│ │ ├── recorded.js
│ │ ├── subscription.js
│ │ └── testscheduler.js
│ ├── webpack.config.js
│ └── webpack.config.production.js
├── tests/
│ ├── concurrency/
│ │ ├── currentthreadscheduler.js
│ │ ├── defaultscheduler.js
│ │ ├── historicalscheduler.js
│ │ ├── immediatescheduler.js
│ │ ├── scheduler-lite.js
│ │ ├── scheduler.js
│ │ └── virtualtimescheduler.js
│ ├── core/
│ │ ├── notification.js
│ │ ├── observable.js
│ │ ├── observer-extras.js
│ │ ├── observer-lite.js
│ │ └── observer.js
│ ├── disposables/
│ │ ├── compositedisposable.js
│ │ ├── disposable.js
│ │ ├── refcountdisposable.js
│ │ ├── serialdisposable.js
│ │ └── singleassignmentdisposable.js
│ ├── helpers/
│ │ ├── mockiterable.js
│ │ └── reactiveassert.js
│ ├── internal/
│ │ ├── isequal.js
│ │ └── trycatch.js
│ ├── observable/
│ │ ├── amb.js
│ │ ├── asobservable.js
│ │ ├── average.js
│ │ ├── buffer.js
│ │ ├── bufferwithcount.js
│ │ ├── bufferwithtime.js
│ │ ├── bufferwithtimeorcount.js
│ │ ├── case.js
│ │ ├── catch.js
│ │ ├── combinelatest.js
│ │ ├── concat.js
│ │ ├── concatmap.js
│ │ ├── concatmapobserver.js
│ │ ├── connectableobservable.js
│ │ ├── controlled.js
│ │ ├── count.js
│ │ ├── create.js
│ │ ├── debounce.js
│ │ ├── defaultifempty.js
│ │ ├── defer.js
│ │ ├── delay.js
│ │ ├── delaysubscription.js
│ │ ├── distinct.js
│ │ ├── distinctuntilchanged.js
│ │ ├── do.js
│ │ ├── dowhile.js
│ │ ├── elementat.js
│ │ ├── empty.js
│ │ ├── every.js
│ │ ├── expand.js
│ │ ├── finally.js
│ │ ├── find.js
│ │ ├── findindex.js
│ │ ├── first.js
│ │ ├── for.js
│ │ ├── forkjoin.js
│ │ ├── from.js
│ │ ├── fromarray.js
│ │ ├── fromcallback.js
│ │ ├── fromevent.js
│ │ ├── fromeventpattern.js
│ │ ├── fromnodecallback.js
│ │ ├── frompromise.js
│ │ ├── generate.js
│ │ ├── generatewithabsolutetime.js
│ │ ├── generatewithrelativetime.js
│ │ ├── groupby.js
│ │ ├── groupbyuntil.js
│ │ ├── groupjoin.js
│ │ ├── if.js
│ │ ├── ignoreelements.js
│ │ ├── includes.js
│ │ ├── indexof.js
│ │ ├── interval.js
│ │ ├── isempty.js
│ │ ├── join.js
│ │ ├── jortsort.js
│ │ ├── jortsortuntil.js
│ │ ├── last.js
│ │ ├── lastindexof.js
│ │ ├── let.js
│ │ ├── manyselect.js
│ │ ├── materialize.js
│ │ ├── max.js
│ │ ├── maxby.js
│ │ ├── merge.js
│ │ ├── mergeall.js
│ │ ├── mergeconcat.js
│ │ ├── mergedelayerror.js
│ │ ├── min.js
│ │ ├── minby.js
│ │ ├── multicast.js
│ │ ├── never.js
│ │ ├── observeon.js
│ │ ├── of.js
│ │ ├── ofarraychanges.js
│ │ ├── ofobjectchanges.js
│ │ ├── onerrorresumenext.js
│ │ ├── pairs.js
│ │ ├── pairwise.js
│ │ ├── partition.js
│ │ ├── pausable.js
│ │ ├── pausablebuffered.js
│ │ ├── pluck.js
│ │ ├── publish.js
│ │ ├── publishlast.js
│ │ ├── publishvalue.js
│ │ ├── range.js
│ │ ├── reduce.js
│ │ ├── repeat.js
│ │ ├── repeatwhen.js
│ │ ├── replay.js
│ │ ├── retry.js
│ │ ├── retrywhen.js
│ │ ├── return.js
│ │ ├── sample.js
│ │ ├── scan.js
│ │ ├── select.js
│ │ ├── selectmany.js
│ │ ├── selectmanyobserver.js
│ │ ├── sequenceequal.js
│ │ ├── single.js
│ │ ├── singleinstance.js
│ │ ├── skip.js
│ │ ├── skiplast.js
│ │ ├── skiplastwithtime.js
│ │ ├── skipuntil.js
│ │ ├── skipuntilwithtime.js
│ │ ├── skipwhile.js
│ │ ├── skipwithtime.js
│ │ ├── slice.js
│ │ ├── some.js
│ │ ├── spawn.js
│ │ ├── start.js
│ │ ├── startwith.js
│ │ ├── subscribeon.js
│ │ ├── sum.js
│ │ ├── switch.js
│ │ ├── take.js
│ │ ├── takelast.js
│ │ ├── takelastbuffer.js
│ │ ├── takelastbufferwithtime.js
│ │ ├── takelastwithtime.js
│ │ ├── takeuntil.js
│ │ ├── takeuntilwithtime.js
│ │ ├── takewhile.js
│ │ ├── takewithtime.js
│ │ ├── throttle.js
│ │ ├── throw.js
│ │ ├── timeinterval.js
│ │ ├── timeout.js
│ │ ├── timer.js
│ │ ├── timestamp.js
│ │ ├── toarray.js
│ │ ├── toasync.js
│ │ ├── tomap.js
│ │ ├── topromise.js
│ │ ├── toset.js
│ │ ├── transduce.js
│ │ ├── using.js
│ │ ├── when.js
│ │ ├── where.js
│ │ ├── while.js
│ │ ├── window.js
│ │ ├── windowwithcount.js
│ │ ├── windowwithtime.js
│ │ ├── windowwithtimeorcount.js
│ │ ├── withlatestfrom.js
│ │ └── zip.js
│ ├── perf/
│ │ ├── old/
│ │ │ ├── rx.aggregates.js
│ │ │ ├── rx.all.compat.js
│ │ │ ├── rx.all.js
│ │ │ ├── rx.async.compat.js
│ │ │ ├── rx.async.js
│ │ │ ├── rx.backpressure.js
│ │ │ ├── rx.binding.js
│ │ │ ├── rx.coincidence.js
│ │ │ ├── rx.compat.js
│ │ │ ├── rx.experimental.js
│ │ │ ├── rx.joinpatterns.js
│ │ │ ├── rx.js
│ │ │ ├── rx.lite.compat.js
│ │ │ ├── rx.lite.extras.js
│ │ │ ├── rx.lite.js
│ │ │ ├── rx.sorting.js
│ │ │ ├── rx.testing.js
│ │ │ ├── rx.time.js
│ │ │ └── rx.virtualtime.js
│ │ ├── operators/
│ │ │ ├── combinelatest.js
│ │ │ ├── concat.js
│ │ │ ├── concatmap.js
│ │ │ ├── count.js
│ │ │ ├── defer.js
│ │ │ ├── distinctuntilchanged.js
│ │ │ ├── empty.js
│ │ │ ├── filter.js
│ │ │ ├── finally.js
│ │ │ ├── flatmap.js
│ │ │ ├── forkjoin.js
│ │ │ ├── from.js
│ │ │ ├── fromarray.js
│ │ │ ├── fromcallback.js
│ │ │ ├── fromnodecallback.js
│ │ │ ├── frompromise.js
│ │ │ ├── ignoreelements.js
│ │ │ ├── just.js
│ │ │ ├── map.js
│ │ │ ├── materialize.js
│ │ │ ├── mergeall.js
│ │ │ ├── mergeproto.js
│ │ │ ├── never.js
│ │ │ ├── of.js
│ │ │ ├── pairs.js
│ │ │ ├── range.js
│ │ │ ├── reduce.js
│ │ │ ├── repeat.js
│ │ │ ├── scan.js
│ │ │ ├── skip.js
│ │ │ ├── skipuntil.js
│ │ │ ├── switch.js
│ │ │ ├── take.js
│ │ │ ├── takeuntil.js
│ │ │ ├── throw.js
│ │ │ ├── toarray.js
│ │ │ ├── withlatestfrom.js
│ │ │ └── zip.js
│ │ └── vendor/
│ │ ├── benchmark.js
│ │ └── rsvp-latest.js
│ ├── rx.aggregates.html
│ ├── rx.all.compat.html
│ ├── rx.all.html
│ ├── rx.async.compat.html
│ ├── rx.async.html
│ ├── rx.backpressure.html
│ ├── rx.binding.html
│ ├── rx.coincidence.html
│ ├── rx.compat.html
│ ├── rx.core.binding.html
│ ├── rx.core.html
│ ├── rx.experimental.html
│ ├── rx.html
│ ├── rx.joinpatterns.html
│ ├── rx.lite.compat.html
│ ├── rx.lite.extras.html
│ ├── rx.lite.html
│ ├── rx.time.html
│ ├── rx.virtualtime.html
│ ├── subjects/
│ │ ├── asyncsubject.js
│ │ ├── behaviorsubject.js
│ │ ├── replaysubject.js
│ │ └── subject.js
│ └── vendor/
│ ├── es5-shim.js
│ ├── es6-shim.js
│ ├── qunit-1.11.0.css
│ ├── qunit-1.11.0.js
│ ├── rsvp.js
│ └── transducers-0.4.158-min.js
├── travis.sh
└── ts/
├── core/
│ ├── abstractobserver.ts
│ ├── anonymousobservable.ts
│ ├── anonymousobserver.ts
│ ├── backpressure/
│ │ ├── controlled.ts
│ │ ├── pausable.ts
│ │ ├── pausablebuffered.ts
│ │ ├── pauser.ts
│ │ ├── stopandwait.ts
│ │ └── windowed.ts
│ ├── checkedobserver.ts
│ ├── concurrency/
│ │ ├── currentthreadscheduler.ts
│ │ ├── defaultscheduler.ts
│ │ ├── historicalscheduler.ts
│ │ ├── immediatescheduler.ts
│ │ ├── scheduleditem.ts
│ │ ├── scheduleperiodicrecursive.ts
│ │ ├── scheduler.periodic.ts
│ │ ├── scheduler.recursive.ts
│ │ ├── scheduler.ts
│ │ ├── scheduler.wrappers.ts
│ │ └── virtualtimescheduler.ts
│ ├── disposables/
│ │ ├── booleandisposable.ts
│ │ ├── compositedisposable.ts
│ │ ├── disposable.ts
│ │ └── refcountdisposable.ts
│ ├── es5.ts
│ ├── es6-iterable.d.ts
│ ├── es6-promise.d.ts
│ ├── es6.ts
│ ├── internal/
│ │ ├── bindcallback.ts
│ │ ├── errors.ts
│ │ ├── isequal.ts
│ │ ├── priorityqueue.ts
│ │ └── util.ts
│ ├── joins/
│ │ ├── pattern.ts
│ │ └── plan.ts
│ ├── linq/
│ │ ├── connectableobservable.ts
│ │ ├── groupedobservable.ts
│ │ └── observable/
│ │ ├── amb.ts
│ │ ├── ambproto.ts
│ │ ├── and.ts
│ │ ├── asobservable.ts
│ │ ├── average.ts
│ │ ├── buffer.ts
│ │ ├── bufferwithcount.ts
│ │ ├── bufferwithtime.ts
│ │ ├── bufferwithtimeorcount.ts
│ │ ├── case.ts
│ │ ├── catch.ts
│ │ ├── catchproto.ts
│ │ ├── combinelatest.ts
│ │ ├── combinelatestproto.ts
│ │ ├── concat.ts
│ │ ├── concatall.ts
│ │ ├── concatmap.ts
│ │ ├── concatmapobserver.ts
│ │ ├── concatproto.ts
│ │ ├── count.ts
│ │ ├── create.ts
│ │ ├── debounce.ts
│ │ ├── defaultifempty.ts
│ │ ├── defer.ts
│ │ ├── delay.ts
│ │ ├── delaysubscription.ts
│ │ ├── dematerialize.ts
│ │ ├── distinct.ts
│ │ ├── distinctuntilchanged.ts
│ │ ├── dowhile.ts
│ │ ├── elementat.ts
│ │ ├── empty.ts
│ │ ├── every.ts
│ │ ├── expand.ts
│ │ ├── filter.ts
│ │ ├── finally.ts
│ │ ├── find.ts
│ │ ├── findindex.ts
│ │ ├── first.ts
│ │ ├── flatmap.ts
│ │ ├── flatmapfirst.ts
│ │ ├── flatmaplatest.ts
│ │ ├── flatmapwithmaxconcurrent.ts
│ │ ├── for.ts
│ │ ├── forkjoin.ts
│ │ ├── forkjoinproto.ts
│ │ ├── from.ts
│ │ ├── fromarray.ts
│ │ ├── fromcallback.ts
│ │ ├── fromevent.ts
│ │ ├── fromeventpattern.ts
│ │ ├── fromnodecallback.ts
│ │ ├── frompromise.ts
│ │ ├── generate.ts
│ │ ├── generatewithabsolutetime.ts
│ │ ├── generatewithrelativetime.ts
│ │ ├── groupby.ts
│ │ ├── groupbyuntil.ts
│ │ ├── groupjoin.ts
│ │ ├── if.ts
│ │ ├── ignoreelements.ts
│ │ ├── includes.ts
│ │ ├── indexof.ts
│ │ ├── interval.ts
│ │ ├── isempty.ts
│ │ ├── join.ts
│ │ ├── jortsort.ts
│ │ ├── jortsortuntil.ts
│ │ ├── just.ts
│ │ ├── last.ts
│ │ ├── let.ts
│ │ ├── manyselect.ts
│ │ ├── map.ts
│ │ ├── materialize.ts
│ │ ├── max.ts
│ │ ├── maxby.ts
│ │ ├── merge.ts
│ │ ├── mergeall.ts
│ │ ├── mergeconcat.ts
│ │ ├── mergedelayerror.ts
│ │ ├── min.ts
│ │ ├── minby.ts
│ │ ├── multicast.ts
│ │ ├── never.ts
│ │ ├── observeon.ts
│ │ ├── of.ts
│ │ ├── ofarraychanges.ts
│ │ ├── ofobjectchanges.ts
│ │ ├── onerrorresumenext.ts
│ │ ├── onerrorresumenextproto.ts
│ │ ├── pairs.ts
│ │ ├── pairwise.ts
│ │ ├── partition.ts
│ │ ├── pipe.ts
│ │ ├── pluck.ts
│ │ ├── publish.ts
│ │ ├── publishlast.ts
│ │ ├── publishvalue.ts
│ │ ├── range.ts
│ │ ├── reduce.ts
│ │ ├── repeat.ts
│ │ ├── repeatproto.ts
│ │ ├── replay.ts
│ │ ├── retry.ts
│ │ ├── retrywhen.ts
│ │ ├── sample.ts
│ │ ├── scan.ts
│ │ ├── selectmanyobserver.ts
│ │ ├── sequenceequal.ts
│ │ ├── share.ts
│ │ ├── sharereplay.ts
│ │ ├── sharevalue.ts
│ │ ├── single.ts
│ │ ├── singleinstance.ts
│ │ ├── skip.ts
│ │ ├── skiplast.ts
│ │ ├── skiplastwithtime.ts
│ │ ├── skipuntil.ts
│ │ ├── skipuntilwithtime.ts
│ │ ├── skipwhile.ts
│ │ ├── skipwithtime.ts
│ │ ├── some.ts
│ │ ├── spawn.ts
│ │ ├── start.ts
│ │ ├── startasync.ts
│ │ ├── startwith.ts
│ │ ├── subscribeon.ts
│ │ ├── sum.ts
│ │ ├── switch.ts
│ │ ├── switchfirst.ts
│ │ ├── take.ts
│ │ ├── takelast.ts
│ │ ├── takelastbuffer.ts
│ │ ├── takelastbufferwithtime.ts
│ │ ├── takelastwithtime.ts
│ │ ├── takeuntil.ts
│ │ ├── takeuntilwithtime.ts
│ │ ├── takewhile.ts
│ │ ├── takewithtime.ts
│ │ ├── tap.ts
│ │ ├── thendo.ts
│ │ ├── throttle.ts
│ │ ├── throw.ts
│ │ ├── timeinterval.ts
│ │ ├── timeout.ts
│ │ ├── timer.ts
│ │ ├── timestamp.ts
│ │ ├── toarray.ts
│ │ ├── toasync.ts
│ │ ├── tomap.ts
│ │ ├── topromise.ts
│ │ ├── toset.ts
│ │ ├── transduce.ts
│ │ ├── using.ts
│ │ ├── when.ts
│ │ ├── while.ts
│ │ ├── window.ts
│ │ ├── windowwithcount.ts
│ │ ├── windowwithtime.ts
│ │ ├── windowwithtimeorcount.ts
│ │ ├── withlatestfrom.ts
│ │ ├── zip.ts
│ │ └── zipiterable.ts
│ ├── notification.ts
│ ├── observable.ts
│ ├── observer-extras.ts
│ ├── observer-lite.ts
│ ├── observer.ts
│ ├── scheduledobserver.ts
│ ├── subjects/
│ │ ├── anonymoussubject.ts
│ │ ├── asyncsubject.ts
│ │ ├── behaviorsubject.ts
│ │ ├── replaysubject.ts
│ │ └── subject.ts
│ └── testing/
│ ├── mockdisposable.ts
│ ├── mockobserver.ts
│ ├── reactivetest.ts
│ ├── recorded.ts
│ ├── subscription.ts
│ └── testscheduler.ts
├── es6-promise.es6.d.ts
├── iterable.es6.d.ts
├── rx.aggregates.d.ts
├── rx.aggregates.es6.d.ts
├── rx.all.d.ts
├── rx.all.es6.d.ts
├── rx.async.d.ts
├── rx.async.es6.d.ts
├── rx.backpressure.d.ts
├── rx.backpressure.es6.d.ts
├── rx.binding.d.ts
├── rx.binding.es6.d.ts
├── rx.coincidence.d.ts
├── rx.coincidence.es6.d.ts
├── rx.core.binding.d.ts
├── rx.core.binding.es6.d.ts
├── rx.core.d.ts
├── rx.core.es6.d.ts
├── rx.core.testing.d.ts
├── rx.core.testing.es6.d.ts
├── rx.d.ts
├── rx.es6.d.ts
├── rx.experimental.d.ts
├── rx.experimental.es6.d.ts
├── rx.joinpatterns.d.ts
├── rx.joinpatterns.es6.d.ts
├── rx.lite.d.ts
├── rx.lite.es6.d.ts
├── rx.lite.extras.d.ts
├── rx.lite.extras.es6.d.ts
├── rx.sorting.d.ts
├── rx.sorting.es6.d.ts
├── rx.testing.d.ts
├── rx.testing.es6.d.ts
├── rx.time.d.ts
├── rx.time.es6.d.ts
├── rx.virtualtime.d.ts
├── rx.virtualtime.es6.d.ts
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .coveralls.yml
================================================
service_name: travis-pro
repo_token: 8YyWggHYCJrQmm4qdV2f5LVvo3vBD7Xsa
================================================
FILE: .editorconfig
================================================
root = true
[*]
end_of_line = lf
insert_final_newline = false
indent_style = space
indent_size = 2
================================================
FILE: .gitattributes
================================================
* text eol=lf
*.png -text
*.exe -text
*.jpg -text
*.txt -text
================================================
FILE: .gitignore
================================================
.idea/
.DS_Store
node_modules
npm-debug.log
.vscode/
================================================
FILE: .jamignore
================================================
.*
*.bat
*.md
*.min.*
*.txt
*.log
package.json
node_modules
doc
examples
src
tests
.nuget
nuget
================================================
FILE: .jscsrc
================================================
{
"excludeFiles": [
"src/core/asyncintro.js",
"src/core/intro.js",
"src/core/outro.js",
"src/core/suboutro.js",
"src/core/subintro.js",
"src/core/testintro.js"
],
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireOperatorBeforeLineBreak": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"disallowMultipleLineStrings": true,
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"return",
"try",
"catch"
],
"requireSpaceBeforeBinaryOperators": [
"=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
"&=", "|=", "^=", "+=",
"+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
"|", "^", "&&", "||", "===", "==", ">=",
"<=", "<", ">", "!=", "!=="
],
"requireSpaceAfterBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpaceBeforeBlockStatements": true,
"requireLineFeedAtFileEnd": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInsideParentheses": true,
"disallowMultipleLineBreaks": true,
"disallowNewlineBeforeBlockStatements": true
}
================================================
FILE: .jscsrc.todo
================================================
{
"maximumLineLength": {
"value": 80,
"allowComments": true,
"allowRegex": true
},
"validateIndentation": 2,
"validateQuoteMarks": "'",
"disallowMultipleVarDecl": true,
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideObjectBrackets": "all",
"disallowSpacesInsideArrayBrackets": "all",
"validateJSDoc": {
"checkParamNames": true,
"requireParamTypes": true
}
}
================================================
FILE: .jshintrc
================================================
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": true,
"boss": true,
"eqnull": true,
"node": true,
"-W030": true,
"predef": [ "Promise" ]
}
================================================
FILE: .npmignore
================================================
node_modules/
modules/
.npm-debug.log
.nuget/
.vscode/
nuget/
doc/
examples/
tests/
logos/
modules/
src/
.git*
.jshint*
.npmignore
.travis.yml
CHANGELOG.*
Gruntfile.js
travis.sh
================================================
FILE: .nuget/nuget.config
================================================
================================================
FILE: .nuget/nuget.targets
================================================
$(MSBuildProjectDirectory)\..\$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))$([System.IO.Path]::Combine($(SolutionDir), "packages"))$(SolutionDir).nugetpackages.config$(SolutionDir)packages$(NuGetToolsPath)\nuget.exe"$(NuGetExePath)"mono --runtime=v4.0.30319 $(NuGetExePath)$(TargetDir.Trim('\\'))""falsefalse$(NuGetCommand) install "$(PackagesConfig)" -source $(PackageSources) -o "$(PackagesDir)"$(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols
RestorePackages;
$(BuildDependsOn);
$(BuildDependsOn);
BuildPackage;
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- "0.10"
- "0.12"
- 4
- 5
env:
global:
- secure: "JwyiLIEV6S7wzr9eUgQ/rP8BeeSY6ZabknHpUKSk4miA7d+/acFeuMAYu0d79BG8ndFIdG9EYbA7ZY1TH/metqDTrExzYLooa0XrAYg2x+cDSboII9albVn5bvdmmWIcgcmcZwKvi5JYLHWcA3Px84Aaf3YXN9V4lS1uLhl0eBI="
- secure: "BVYlZy3vIt21bhrzKPgQzRlbwGCBrdBtRPRvX/qCGi1jYAoAtrT0bYllZpNqduPLouW3LaJDwOJx9zLDmZDwKDvPgTinpVwmkhZYRFl1kNweku3ZfeHR5ejOVYvdQEqVU4rOtTBLk6emItEPTuFtC9SPSYQZQtjnZAjHTg0jqLU="
notifications:
slack: reactivex:e424dAgQ2W9kuRMe6ngxHQbv
webhooks:
urls:
- https://webhooks.gitter.im/e/8f1482d7420d95b647ce
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
================================================
FILE: Gruntfile.js
================================================
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
banner:
'/*'+
'Copyright (c) Microsoft. All rights reserved.\r\n' +
'Microsoft Open Technologies. Licensed under the Apache License, Version 2.0 (the "License"); you.\r\n' +
'may not use this file except in compliance with the License. You may.\r\n' +
'obtain a copy of the License at.\r\n\r\n' +
'http://www.apache.org/licenses/LICENSE-2.0.\r\n\r\n' +
'Unless required by applicable law or agreed to in writing, software.\r\n' +
'distributed under the License is distributed on an "AS IS" BASIS,.\r\n' +
'WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or.\r\n' +
'implied. See the License for the specific language governing permissions.\r\n' +
'and limitations under the License..\r\n' +
'*/'
},
concat: {
core: {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/coreheader.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
// internals
'src/core/internal/util.js',
// Disposables
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
// Schedulers
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/internal/priorityqueue.js',
// Observer
'src/core/observer-lite.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
// Observable
'src/core/observable.js',
'src/core/anonymousobservable.js',
'src/core/perf/observablebase.js',
'src/core/autodetachobserver.js',
'src/core/linq/observable/create.js',
'src/core/headers/exports.js',
// Long stacktrace end
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js'
],
dest: 'dist/rx.core.js'
},
'core-binding': {
src: [
'src/core/headers/license.js',
'src/core/headers/core-intro.js',
'src/core/headers/core-bindingheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/multicast.js',
'src/core/linq/observable/publish.js',
'src/core/linq/observable/share.js',
'src/core/linq/observable/publishlast.js',
'src/core/linq/observable/publishvalue.js',
'src/core/linq/observable/sharevalue.js',
'src/core/linq/observable/replay.js',
'src/core/linq/observable/sharereplay.js',
'src/core/scheduledobserver.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/behaviorsubject.js',
'src/core/subjects/replaysubject.js',
'src/core/linq/connectableobservable.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.core.binding.js'
},
'core-testing': {
src: [
'src/core/headers/license.js',
'src/core/headers/core-intro.js',
'src/core/headers/core-testheader.js',
'src/core/notification.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/virtualtimescheduler.js',
'src/core/testing/reactivetest.js',
'src/core/testing/recorded.js',
'src/core/testing/subscription.js',
'src/core/testing/mockdisposable.js',
'src/core/testing/mockobserver.js',
'src/core/testing/mockpromise.js',
'src/core/testing/hotobservable.js',
'src/core/testing/coldobservable.js',
'src/core/testing/testscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.core.testing.js'
},
all: {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/basicheader.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
'src/core/internal/errors.js',
'src/core/headers/enumeratorheader.js',
'src/core/internal/bindcallback.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/internal/util.js',
'src/core/internal/priorityqueue.js',
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
'src/core/disposables/refcountdisposable.js',
'src/core/disposables/scheduleddisposable.js',
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/scheduler.wrappers.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/concurrency/catchscheduler.js',
'src/core/notification.js',
'src/core/observer.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
'src/core/checkedobserver.js',
'src/core/scheduledobserver.js',
'src/core/observeonobserver.js',
'src/core/observable.js',
'src/core/perf/observablebase.js',
'src/core/perf/operators/flatmapbase.js',
'src/core/enumerable.js',
// Concurrency
'src/core/linq/observable/observeon.js', // ObserveOnObserver
'src/core/linq/observable/subscribeon.js', // SingleAssignmentDisposable, SerialDisposable, ScheduleDisposable
// Async
'src/core/perf/operators/frompromise.js', // AsyncSubject, asObservable
'src/core/linq/observable/topromise.js',
// Creation
'src/core/perf/operators/toarray.js',
'src/core/linq/observable/create.js',
'src/core/linq/observable/defer.js',
'src/core/perf/operators/empty.js',
'src/core/perf/operators/from.js',
'src/core/perf/operators/fromarrayobservable.js','src/core/perf/operators/fromarray.js',
'src/core/linq/observable/generate.js',
'src/core/perf/operators/of.js',
'src/core/linq/observable/ofarraychanges.js',
'src/core/linq/observable/ofobjectchanges.js',
'src/core/perf/operators/never.js',
'src/core/perf/operators/pairs.js',
'src/core/perf/operators/range.js',
'src/core/perf/operators/repeat.js',
'src/core/perf/operators/just.js',
'src/core/perf/operators/throw.js',
'src/core/linq/observable/using.js',
// Multiple
'src/core/linq/observable/ambproto.js',
'src/core/linq/observable/amb.js',
'src/core/linq/observable/catchproto.js',
'src/core/linq/observable/catch.js',
'src/core/linq/observable/combinelatestproto.js',
'src/core/perf/operators/combinelatest.js',
'src/core/linq/observable/concatproto.js',
'src/core/perf/operators/concat.js',
'src/core/linq/observable/concatall.js',
'src/core/perf/operators/mergeconcat.js',
'src/core/linq/observable/merge.js',
'src/core/perf/operators/mergeall.js',
'src/core/linq/observable/mergedelayerror.js',
'src/core/linq/observable/onerrorresumenextproto.js',
'src/core/linq/observable/onerrorresumenext.js',
'src/core/perf/operators/skipuntil.js',
'src/core/perf/operators/switch.js',
'src/core/perf/operators/takeuntil.js',
'src/core/perf/operators/withlatestfrom.js',
'src/core/perf/operators/zip.js',
'src/core/linq/observable/zip.js',
'src/core/linq/observable/zipiterable.js',
// Single
'src/core/linq/observable/asobservable.js',
'src/core/linq/observable/bufferwithcount.js',
'src/core/linq/observable/dematerialize.js',
'src/core/perf/operators/distinctuntilchanged.js',
'src/core/perf/operators/tap.js',
'src/core/perf/operators/finally.js',
'src/core/perf/operators/ignoreelements.js',
'src/core/linq/observable/materialize.js',
'src/core/linq/observable/repeatproto.js',
'src/core/linq/observable/retry.js',
'src/core/linq/observable/retrywhen.js',
'src/core/linq/observable/repeatwhen.js',
'src/core/perf/operators/scan.js',
'src/core/linq/observable/skiplast.js',
'src/core/linq/observable/startwith.js',
'src/core/linq/observable/takelast.js',
'src/core/linq/observable/takelastbuffer.js',
'src/core/linq/observable/windowwithcount.js',
// Standard query operators
'src/core/linq/observable/concatmap.js',
'src/core/linq/observable/concatmapobserver.js',
'src/core/linq/observable/defaultifempty.js',
'src/core/linq/observable/distinct.js',
'src/core/linq/observable/groupby.js',
'src/core/linq/observable/groupbyuntil.js',
'src/core/perf/operators/map.js',
'src/core/linq/observable/pluck.js',
'src/core/perf/operators/flatmap.js',
'src/core/linq/observable/selectmanyobserver.js',
'src/core/perf/operators/flatmaplatest.js',
'src/core/perf/operators/skip.js',
'src/core/linq/observable/skipwhile.js',
'src/core/perf/operators/take.js',
'src/core/linq/observable/takewhile.js',
'src/core/perf/operators/filter.js',
// Aggregate Operators
'src/core/linq/observable/_extremaby.js',
'src/core/linq/observable/_firstonly.js',
'src/core/perf/operators/reduce.js', // scan, startwith, finalvalue
'src/core/linq/observable/some.js', // where
'src/core/linq/observable/isempty.js', // any, select
'src/core/linq/observable/every.js', // where, any
'src/core/linq/observable/includes.js', // where, any
'src/core/linq/observable/count.js', // where, aggregate
'src/core/linq/observable/indexof.js',
'src/core/linq/observable/sum.js', // select, aggregate
'src/core/linq/observable/minby.js', // _extremaby
'src/core/linq/observable/min.js', // minby, _firstonly
'src/core/linq/observable/maxby.js', // _extremaby
'src/core/linq/observable/max.js', // max, _firstonly
'src/core/linq/observable/average.js', // select, scan, aggregate, finalvalue
'src/core/linq/observable/sequenceequal.js', // compositedisposable
'src/core/linq/observable/elementat.js',
'src/core/linq/observable/single.js',
'src/core/linq/observable/first.js',
'src/core/linq/observable/last.js',
'src/core/linq/observable/_findvalue.js',
'src/core/linq/observable/find.js', // _findvalue, where
'src/core/linq/observable/findindex.js', // _findvalue, where
'src/core/linq/observable/toset.js',
'src/core/linq/observable/tomap.js',
'src/core/linq/observable/slice.js',
'src/core/linq/observable/lastindexof.js',
// Async operators
'src/core/linq/observable/spawn.js',
'src/core/linq/observable/start.js', // toasync
'src/core/linq/observable/toasync.js', // AsyncSubject, asObservable
'src/core/perf/operators/fromcallback.js',
'src/core/perf/operators/fromnodecallback.js',
'src/core/linq/observable/fromevent.js', // publish
'src/core/linq/observable/fromeventpattern.js', // publish
'src/core/linq/observable/startasync.js',
// Backpressure operators
'src/core/backpressure/pausable.js',
'src/core/backpressure/pausablebuffered.js',
'src/core/backpressure/controlled.js',
'src/core/backpressure/stopandwait.js',
'src/core/backpressure/windowed.js',
'src/core/linq/observable/pipe.js',
// Binding operators
'src/core/linq/observable/multicast.js', // ConnectableObservable
'src/core/linq/observable/publish.js', // mulitcast, Subject
'src/core/linq/observable/share.js', // mulitcast, Subject, Reference counted
'src/core/linq/observable/publishlast.js', // multicast, AsyncSubject
'src/core/linq/observable/publishvalue.js', // multicast, BehaviorSubject
'src/core/linq/observable/sharevalue.js', // multicast, BehaviorSubject, Reference counted
'src/core/linq/observable/replay.js', // multicast, ReplaySubject
'src/core/linq/observable/sharereplay.js',
'src/core/subjects/innersubscription.js',
'src/core/linq/connectableobservable.js',
'src/core/linq/observable/singleinstance.js',
// Coincidence operators
'src/core/linq/observable/join.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/groupjoin.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/buffer.js', // window, selectMany, toArray
'src/core/linq/observable/window.js', // CompositeDisposable, RefCountDisposable, Subject, SingleAssignmentDisposable
'src/core/linq/observable/pairwise.js',
'src/core/linq/observable/partition.js',
// Experimental operators
'src/core/linq/enumerable/while.js', // Enumerable
'src/core/linq/observable/let.js',
'src/core/linq/observable/if.js', // defer, empty
'src/core/linq/observable/for.js', // Enumerable.forEach, concatproto
'src/core/linq/observable/while.js', // Enumerable.while, concatproto
'src/core/linq/observable/dowhile.js', // Enumerable.while, concat
'src/core/linq/observable/case.js', // defer, empty
'src/core/linq/observable/expand.js', // immediateScheduler, SerialDisposable, CompositeDisposable, SingleAssignmentDisposable
'src/core/linq/observable/forkjoin.js', // CompositeDisposable
'src/core/linq/observable/forkjoinproto.js', // SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/manyselect.js', // ImmediateScheduler, CurrentThreadScheduler, select, do, observeOn
// Join pattern operators
'src/core/internal/map.js',
'src/core/joins/pattern.js',
'src/core/joins/plan.js',
'src/core/joins/activeplan.js',
'src/core/joins/joinobserver.js',
'src/core/linq/observable/and.js', // Pattern
'src/core/linq/observable/thendo.js', // Pattern
'src/core/linq/observable/when.js', // CompositeDisposable
// Time based operators
'src/core/linq/observable/_observabletimer.js', // AnonymousObservable
'src/core/linq/observable/_observabletimerdateandperiod.js', // AnonymousObservable, normalizeTime
'src/core/linq/observable/_observabletimertimespanandperiod.js', // AnonymousObservable, defer, _observabletimerdateandperiod
'src/core/linq/observable/interval.js', // timeoutScheduler, _observabletimertimespanandperiod
'src/core/linq/observable/timer.js', // timeoutScheduler, _observabletimerdate, _observabletimerdateandperiod, _observabletimertimespan, _observabletimertimespanandperiod
'src/core/linq/observable/delay.js', // AnonymousObservable, timeoutScheduler, SerialDisposable, materialize, timestamp
'src/core/linq/observable/debounce.js', // AnonymousObservable, SerialDisposable, timeoutScheduler, SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/windowwithtime.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/windowwithtimeorcount.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/bufferwithtime.js', // windowwithtime, selectMany, toArray
'src/core/linq/observable/bufferwithtimeorcount.js', // windowwithtimeorcount, selectMany, toArray
'src/core/linq/observable/timeinterval.js', // timeoutScheduler, defer, select
'src/core/linq/observable/timestamp.js', // timeoutScheduler, select
'src/core/linq/observable/sample.js', // AnonymousObservable, CompositeDisposable, interval, timeoutScheduler
'src/core/linq/observable/timeout.js', // AnonymousObservable, timeoutScheduler, throw, SingleAssignmentDisposable, SerialDisposable, CompositeDisposable
'src/core/linq/observable/generatewithabsolutetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/generatewithrelativetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/delaysubscription.js', // delayWithSelector, timer, empty
'src/core/linq/observable/skiplastwithtime.js',
'src/core/linq/observable/takelastwithtime.js',
'src/core/linq/observable/takelastbufferwithtime.js',
'src/core/linq/observable/takewithtime.js',
'src/core/linq/observable/skipwithtime.js',
'src/core/linq/observable/skipuntilwithtime.js',
'src/core/linq/observable/takeuntilwithtime.js',
'src/core/linq/observable/throttle.js',
// Transducers
'src/core/linq/observable/transduce.js',
// Experimental Flattening
'src/core/linq/observable/switchfirst.js',
'src/core/perf/operators/flatmapfirst.js',
'src/core/perf/operators/flatmapwithmaxconcurrent.js',
// Virtual time
'src/core/concurrency/virtualtimescheduler.js',
'src/core/concurrency/historicalscheduler.js',
'src/core/testing/reactivetest.js',
'src/core/testing/recorded.js',
'src/core/testing/subscription.js',
'src/core/testing/mockdisposable.js',
'src/core/testing/mockobserver.js',
'src/core/testing/mockpromise.js',
'src/core/testing/hotobservable.js',
'src/core/testing/coldobservable.js',
'src/core/testing/testscheduler.js',
'src/core/anonymousobservable.js',
'src/core/autodetachobserver.js',
'src/core/linq/groupedobservable.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/behaviorsubject.js',
'src/core/subjects/replaysubject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/backpressure/pauser.js',
'src/core/headers/exports.js',
// Long stacktrace end
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js'
],
dest: 'dist/rx.all.js'
},
'all-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/basicheader-compat.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
'src/core/internal/polyfills.js',
'src/core/internal/errors.js',
'src/core/headers/enumeratorheader.js',
'src/core/internal/bindcallback.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/internal/util.js',
'src/core/internal/priorityqueue.js',
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
'src/core/disposables/refcountdisposable.js',
'src/core/disposables/scheduleddisposable.js',
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/scheduler.wrappers.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/concurrency/catchscheduler.js',
'src/core/notification.js',
'src/core/observer.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
'src/core/checkedobserver.js',
'src/core/scheduledobserver.js',
'src/core/observeonobserver.js',
'src/core/observable.js',
'src/core/perf/observablebase.js',
'src/core/perf/operators/flatmapbase.js',
'src/core/enumerable.js',
'src/core/linq/observable/observeon.js', // ObserveOnObserver
'src/core/linq/observable/subscribeon.js', // SingleAssignmentDisposable, SerialDisposable, ScheduleDisposable
// Async
'src/core/perf/operators/frompromise.js', // AsyncSubject, asObservable
'src/core/linq/observable/topromise.js',
// Creation
'src/core/perf/operators/toarray.js',
'src/core/linq/observable/create.js',
'src/core/linq/observable/defer.js',
'src/core/perf/operators/empty.js',
'src/core/perf/operators/from.js',
'src/core/perf/operators/fromarrayobservable.js','src/core/perf/operators/fromarray.js',
'src/core/linq/observable/generate.js',
'src/core/perf/operators/of.js',
'src/core/perf/operators/never.js',
'src/core/perf/operators/pairs.js',
'src/core/perf/operators/range.js',
'src/core/perf/operators/repeat.js',
'src/core/perf/operators/just.js',
'src/core/perf/operators/throw.js',
'src/core/linq/observable/using.js',
// Multiple
'src/core/linq/observable/ambproto.js',
'src/core/linq/observable/amb.js',
'src/core/linq/observable/catchproto.js',
'src/core/linq/observable/catch.js',
'src/core/linq/observable/combinelatestproto.js',
'src/core/perf/operators/combinelatest.js',
'src/core/linq/observable/concatproto.js',
'src/core/perf/operators/concat.js',
'src/core/linq/observable/concatall.js',
'src/core/perf/operators/mergeconcat.js',
'src/core/linq/observable/merge.js',
'src/core/perf/operators/mergeall.js',
'src/core/linq/observable/mergedelayerror.js',
'src/core/linq/observable/onerrorresumenextproto.js',
'src/core/linq/observable/onerrorresumenext.js',
'src/core/perf/operators/skipuntil.js',
'src/core/perf/operators/switch.js',
'src/core/perf/operators/takeuntil.js',
'src/core/perf/operators/withlatestfrom.js',
'src/core/perf/operators/zip.js',
'src/core/linq/observable/zip.js',
'src/core/linq/observable/zipiterable.js',
// Single
'src/core/linq/observable/asobservable.js',
'src/core/linq/observable/bufferwithcount.js',
'src/core/linq/observable/dematerialize.js',
'src/core/perf/operators/distinctuntilchanged.js',
'src/core/perf/operators/tap.js',
'src/core/perf/operators/finally.js',
'src/core/perf/operators/ignoreelements.js',
'src/core/linq/observable/materialize.js',
'src/core/linq/observable/repeatproto.js',
'src/core/linq/observable/retry.js',
'src/core/linq/observable/retrywhen.js',
'src/core/linq/observable/repeatwhen.js',
'src/core/perf/operators/scan.js',
'src/core/linq/observable/skiplast.js',
'src/core/linq/observable/startwith.js',
'src/core/linq/observable/takelast.js',
'src/core/linq/observable/takelastbuffer.js',
'src/core/linq/observable/windowwithcount.js',
// Standard query operators
'src/core/perf/operators/concatmap.js',
'src/core/linq/observable/concatmapobserver.js',
'src/core/linq/observable/defaultifempty.js',
'src/core/linq/observable/distinct.js',
'src/core/linq/observable/groupby.js',
'src/core/linq/observable/groupbyuntil.js',
'src/core/perf/operators/map.js',
'src/core/linq/observable/pluck.js',
'src/core/perf/operators/flatmap.js',
'src/core/linq/observable/selectmanyobserver.js',
'src/core/perf/operators/flatmaplatest.js',
'src/core/perf/operators/skip.js',
'src/core/linq/observable/skipwhile.js',
'src/core/perf/operators/take.js',
'src/core/linq/observable/takewhile.js',
'src/core/perf/operators/filter.js',
// Aggregate operators
'src/core/linq/observable/_extremaby.js',
'src/core/linq/observable/_firstonly.js',
'src/core/perf/operators/reduce.js', // scan, startwith, finalvalue
'src/core/linq/observable/some.js', // where
'src/core/linq/observable/isempty.js', // any, select
'src/core/linq/observable/every.js', // where, any
'src/core/linq/observable/includes.js', // where, any
'src/core/linq/observable/count.js', // where, aggregate
'src/core/linq/observable/indexof.js',
'src/core/linq/observable/sum.js', // select, aggregate
'src/core/linq/observable/minby.js', // _extremaby
'src/core/linq/observable/min.js', // minby, _firstonly
'src/core/linq/observable/maxby.js', // _extremaby
'src/core/linq/observable/max.js', // max, _firstonly
'src/core/linq/observable/average.js', // select, scan, aggregate, finalvalue
'src/core/linq/observable/sequenceequal.js', // compositedisposable
'src/core/linq/observable/elementat.js',
'src/core/linq/observable/single.js',
'src/core/linq/observable/first.js',
'src/core/linq/observable/last.js',
'src/core/linq/observable/_findvalue.js',
'src/core/linq/observable/find.js', // _findvalue, where
'src/core/linq/observable/findindex.js', // _findvalue, where
'src/core/linq/observable/toset.js',
'src/core/linq/observable/tomap.js',
'src/core/linq/observable/slice.js',
'src/core/linq/observable/lastindexof.js',
// Async compat operators
'src/core/linq/observable/spawn.js',
'src/core/linq/observable/start.js', // toasync
'src/core/linq/observable/toasync.js', // asyncsubject, asObservable
'src/core/perf/operators/fromcallback.js',
'src/core/perf/operators/fromnodecallback.js',
'src/core/linq/observable/fromevent.js', // publish
'src/core/linq/observable/fromeventpattern.js', // publish
'src/core/linq/observable/startasync.js',
// Backpressure operators
'src/core/backpressure/pausable.js',
'src/core/backpressure/pausablebuffered.js',
'src/core/backpressure/controlled.js',
'src/core/backpressure/stopandwait.js',
'src/core/backpressure/windowed.js',
'src/core/linq/observable/pipe.js',
// Binding operators
'src/core/linq/observable/multicast.js', // ConnectableObservable
'src/core/linq/observable/publish.js', // mulitcast, Subject
'src/core/linq/observable/share.js', // mulitcast, Subject, Reference counted
'src/core/linq/observable/publishlast.js', // multicast, AsyncSubject
'src/core/linq/observable/publishvalue.js', // multicast, BehaviorSubject
'src/core/linq/observable/sharevalue.js', // multicast, BehaviorSubject, Reference counted
'src/core/linq/observable/replay.js', // multicast, ReplaySubject
'src/core/linq/observable/sharereplay.js',
'src/core/subjects/innersubscription.js',
'src/core/linq/connectableobservable.js',
'src/core/linq/observable/singleinstance.js',
// Coincidence operators
'src/core/linq/observable/join.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/groupjoin.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/buffer.js', // window, selectMany, toArray
'src/core/linq/observable/window.js', // CompositeDisposable, RefCountDisposable, Subject, SingleAssignmentDisposable
'src/core/linq/observable/pairwise.js',
'src/core/linq/observable/partition.js',
// Experimental operators
'src/core/linq/enumerable/while.js', // Enumerable
'src/core/linq/observable/let.js',
'src/core/linq/observable/if.js', // defer, empty
'src/core/linq/observable/for.js', // Enumerable.forEach, concatproto
'src/core/linq/observable/while.js', // Enumerable.while, concatproto
'src/core/linq/observable/dowhile.js', // Enumerable.while, concat
'src/core/linq/observable/case.js', // defer, empty
'src/core/linq/observable/expand.js', // immediateScheduler, SerialDisposable, CompositeDisposable, SingleAssignmentDisposable
'src/core/linq/observable/forkjoin.js', // CompositeDisposable
'src/core/linq/observable/forkjoinproto.js', // SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/manyselect.js', // ImmediateScheduler, CurrentThreadScheduler, select, do, observeOn
// Join pattern operators
'src/core/internal/map.js',
'src/core/joins/pattern.js',
'src/core/joins/plan.js',
'src/core/joins/activeplan.js',
'src/core/joins/joinobserver.js',
'src/core/linq/observable/and.js', // Pattern
'src/core/linq/observable/thendo.js', // Pattern
'src/core/linq/observable/when.js', // CompositeDisposable
// Time based operators
'src/core/linq/observable/_observabletimer.js', // AnonymousObservable
'src/core/linq/observable/_observabletimerdateandperiod.js', // AnonymousObservable, normalizeTime
'src/core/linq/observable/_observabletimertimespanandperiod.js', // AnonymousObservable, defer, _observabletimerdateandperiod
'src/core/linq/observable/interval.js', // timeoutScheduler, _observabletimertimespanandperiod
'src/core/linq/observable/timer.js', // timeoutScheduler, _observabletimerdate, _observabletimerdateandperiod, _observabletimertimespan, _observabletimertimespanandperiod
'src/core/linq/observable/delay.js', // AnonymousObservable, timeoutScheduler, SerialDisposable, materialize, timestamp
'src/core/linq/observable/debounce.js', // AnonymousObservable, SerialDisposable, timeoutScheduler, SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/windowwithtime.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/windowwithtimeorcount.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/bufferwithtime.js', // windowwithtime, selectMany, toArray
'src/core/linq/observable/bufferwithtimeorcount.js', // windowwithtimeorcount, selectMany, toArray
'src/core/linq/observable/timeinterval.js', // timeoutScheduler, defer, select
'src/core/linq/observable/timestamp.js', // timeoutScheduler, select
'src/core/linq/observable/sample.js', // AnonymousObservable, CompositeDisposable, interval, timeoutScheduler
'src/core/linq/observable/timeout.js', // AnonymousObservable, timeoutScheduler, throw, SingleAssignmentDisposable, SerialDisposable, CompositeDisposable
'src/core/linq/observable/generatewithabsolutetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/generatewithrelativetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/delaysubscription.js', // delayWithSelector, timer, empty
'src/core/linq/observable/skiplastwithtime.js',
'src/core/linq/observable/takelastwithtime.js',
'src/core/linq/observable/takelastbufferwithtime.js',
'src/core/linq/observable/takewithtime.js',
'src/core/linq/observable/skipwithtime.js',
'src/core/linq/observable/skipuntilwithtime.js',
'src/core/linq/observable/takeuntilwithtime.js',
'src/core/linq/observable/throttle.js',
// Experimental Flattening
'src/core/linq/observable/switchfirst.js',
'src/core/perf/operators/flatmapfirst.js',
'src/core/perf/operators/flatmapwithmaxconcurrent.js',
// Transducers
'src/core/linq/observable/transduce.js',
// Virtual time
'src/core/concurrency/virtualtimescheduler.js',
'src/core/concurrency/historicalscheduler.js',
'src/core/testing/reactivetest.js',
'src/core/testing/recorded.js',
'src/core/testing/subscription.js',
'src/core/testing/mockdisposable.js',
'src/core/testing/mockobserver.js',
'src/core/testing/mockpromise.js',
'src/core/testing/hotobservable.js',
'src/core/testing/coldobservable.js',
'src/core/testing/testscheduler.js',
'src/core/anonymousobservable.js',
'src/core/autodetachobserver.js',
'src/core/linq/groupedobservable.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/subjects/behaviorsubject.js',
'src/core/subjects/replaysubject.js',
'src/core/backpressure/pauser.js',
'src/core/headers/exports.js',
// End long stack traces
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js',
],
dest: 'dist/rx.all.compat.js'
},
main: {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/basicheader.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
'src/core/internal/errors.js',
'src/core/headers/enumeratorheader.js',
'src/core/internal/bindcallback.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/internal/util.js',
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
'src/core/disposables/refcountdisposable.js',
'src/core/disposables/scheduleddisposable.js',
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/scheduler.wrappers.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/concurrency/catchscheduler.js',
'src/core/internal/priorityqueue.js',
'src/core/notification.js',
'src/core/observer.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
'src/core/checkedobserver.js',
'src/core/scheduledobserver.js',
'src/core/observeonobserver.js',
'src/core/observable.js',
'src/core/perf/observablebase.js',
'src/core/perf/operators/flatmapbase.js',
'src/core/enumerable.js',
// Concurrency
'src/core/linq/observable/observeon.js', // ObserveOnObserver
'src/core/linq/observable/subscribeon.js', // SingleAssignmentDisposable, SerialDisposable, ScheduleDisposable
// Async
'src/core/perf/operators/frompromise.js', // AsyncSubject, asObservable
'src/core/linq/observable/topromise.js',
// Creation
'src/core/perf/operators/toarray.js',
'src/core/linq/observable/create.js',
'src/core/linq/observable/defer.js',
'src/core/perf/operators/empty.js',
'src/core/perf/operators/from.js',
'src/core/perf/operators/fromarrayobservable.js','src/core/perf/operators/fromarray.js',
'src/core/linq/observable/generate.js',
'src/core/perf/operators/never.js',
'src/core/perf/operators/of.js',
'src/core/perf/operators/pairs.js',
'src/core/perf/operators/range.js',
'src/core/perf/operators/repeat.js',
'src/core/perf/operators/just.js',
'src/core/perf/operators/throw.js',
'src/core/linq/observable/using.js',
// Multiple
'src/core/linq/observable/ambproto.js',
'src/core/linq/observable/amb.js',
'src/core/linq/observable/catchproto.js',
'src/core/linq/observable/catch.js',
'src/core/linq/observable/combinelatestproto.js',
'src/core/perf/operators/combinelatest.js',
'src/core/linq/observable/concatproto.js',
'src/core/perf/operators/concat.js',
'src/core/linq/observable/concatall.js',
'src/core/perf/operators/mergeconcat.js',
'src/core/linq/observable/merge.js',
'src/core/linq/observable/mergedelayerror.js',
'src/core/perf/operators/mergeall.js',
'src/core/linq/observable/onerrorresumenextproto.js',
'src/core/linq/observable/onerrorresumenext.js',
'src/core/perf/operators/skipuntil.js',
'src/core/perf/operators/switch.js',
'src/core/perf/operators/takeuntil.js',
'src/core/perf/operators/withlatestfrom.js',
'src/core/perf/operators/zip.js',
'src/core/linq/observable/zip.js',
'src/core/linq/observable/zipiterable.js',
// Single
'src/core/linq/observable/asobservable.js',
'src/core/linq/observable/bufferwithcount.js',
'src/core/linq/observable/dematerialize.js',
'src/core/perf/operators/distinctuntilchanged.js',
'src/core/perf/operators/tap.js',
'src/core/perf/operators/finally.js',
'src/core/perf/operators/ignoreelements.js',
'src/core/linq/observable/materialize.js',
'src/core/linq/observable/repeatproto.js',
'src/core/linq/observable/retry.js',
'src/core/linq/observable/retrywhen.js',
'src/core/linq/observable/repeatwhen.js',
'src/core/perf/operators/scan.js',
'src/core/linq/observable/skiplast.js',
'src/core/linq/observable/startwith.js',
'src/core/linq/observable/takelast.js',
'src/core/linq/observable/takelastbuffer.js',
'src/core/linq/observable/windowwithcount.js',
// Standard query operators
'src/core/perf/operators/concatmap.js',
'src/core/linq/observable/concatmapobserver.js',
'src/core/linq/observable/defaultifempty.js',
'src/core/linq/observable/distinct.js',
'src/core/perf/operators/map.js',
'src/core/linq/observable/pluck.js',
'src/core/linq/observable/selectmanyobserver.js',
'src/core/perf/operators/flatmap.js',
'src/core/perf/operators/flatmaplatest.js',
'src/core/perf/operators/skip.js',
'src/core/linq/observable/skipwhile.js',
'src/core/perf/operators/take.js',
'src/core/linq/observable/takewhile.js',
'src/core/perf/operators/filter.js',
// Transducers
'src/core/linq/observable/transduce.js',
'src/core/anonymousobservable.js',
'src/core/autodetachobserver.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/headers/exports.js',
// Long stack trace end
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js',
],
dest: 'dist/rx.js'
},
'main-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/basicheader-compat.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
'src/core/internal/polyfills.js',
'src/core/internal/errors.js',
'src/core/headers/enumeratorheader.js',
'src/core/internal/bindcallback.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/internal/util.js',
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
'src/core/disposables/refcountdisposable.js',
'src/core/disposables/scheduleddisposable.js',
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/scheduler.wrappers.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/concurrency/catchscheduler.js',
'src/core/internal/priorityqueue.js',
'src/core/notification.js',
'src/core/observer.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
'src/core/checkedobserver.js',
'src/core/scheduledobserver.js',
'src/core/observeonobserver.js',
'src/core/observable.js',
'src/core/perf/observablebase.js',
'src/core/perf/operators/flatmapbase.js',
'src/core/enumerable.js',
'src/core/linq/observable/observeon.js', // ObserveOnObserver
'src/core/linq/observable/subscribeon.js', // SingleAssignmentDisposable, SerialDisposable, ScheduleDisposable
// Async
'src/core/perf/operators/frompromise.js', // AsyncSubject, asObservable
'src/core/linq/observable/topromise.js',
// Creation
'src/core/perf/operators/toarray.js',
'src/core/linq/observable/create.js',
'src/core/linq/observable/defer.js',
'src/core/perf/operators/empty.js',
'src/core/perf/operators/from.js',
'src/core/perf/operators/fromarrayobservable.js','src/core/perf/operators/fromarray.js',
'src/core/linq/observable/generate.js',
'src/core/perf/operators/never.js',
'src/core/perf/operators/of.js',
'src/core/perf/operators/pairs.js',
'src/core/perf/operators/range.js',
'src/core/perf/operators/repeat.js',
'src/core/perf/operators/just.js',
'src/core/perf/operators/throw.js',
'src/core/linq/observable/using.js',
// Multiple
'src/core/linq/observable/ambproto.js',
'src/core/linq/observable/amb.js',
'src/core/linq/observable/catchproto.js',
'src/core/linq/observable/catch.js',
'src/core/linq/observable/combinelatestproto.js',
'src/core/perf/operators/combinelatest.js',
'src/core/linq/observable/concatproto.js',
'src/core/perf/operators/concat.js',
'src/core/linq/observable/concatall.js',
'src/core/perf/operators/mergeconcat.js',
'src/core/linq/observable/merge.js',
'src/core/perf/operators/mergeall.js',
'src/core/linq/observable/mergedelayerror.js',
'src/core/linq/observable/onerrorresumenextproto.js',
'src/core/linq/observable/onerrorresumenext.js',
'src/core/perf/operators/skipuntil.js',
'src/core/perf/operators/switch.js',
'src/core/perf/operators/takeuntil.js',
'src/core/perf/operators/withlatestfrom.js',
'src/core/perf/operators/zip.js',
'src/core/linq/observable/zip.js',
'src/core/linq/observable/zipiterable.js',
// Single
'src/core/linq/observable/asobservable.js',
'src/core/linq/observable/bufferwithcount.js',
'src/core/linq/observable/dematerialize.js',
'src/core/perf/operators/distinctuntilchanged.js',
'src/core/perf/operators/tap.js',
'src/core/perf/operators/finally.js',
'src/core/perf/operators/ignoreelements.js',
'src/core/linq/observable/materialize.js',
'src/core/linq/observable/repeatproto.js',
'src/core/linq/observable/retry.js',
'src/core/linq/observable/retrywhen.js',
'src/core/linq/observable/repeatwhen.js',
'src/core/perf/operators/scan.js',
'src/core/linq/observable/skiplast.js',
'src/core/linq/observable/startwith.js',
'src/core/linq/observable/takelast.js',
'src/core/linq/observable/takelastbuffer.js',
'src/core/linq/observable/windowwithcount.js',
// Standard query operators
'src/core/perf/operators/concatmap.js',
'src/core/linq/observable/concatmapobserver.js',
'src/core/linq/observable/defaultifempty.js',
'src/core/linq/observable/distinct.js',
'src/core/perf/operators/map.js',
'src/core/linq/observable/pluck.js',
'src/core/perf/operators/flatmap.js',
'src/core/linq/observable/selectmanyobserver.js',
'src/core/perf/operators/flatmaplatest.js',
'src/core/perf/operators/skip.js',
'src/core/linq/observable/skipwhile.js',
'src/core/perf/operators/take.js',
'src/core/linq/observable/takewhile.js',
'src/core/perf/operators/filter.js',
// Transducers
'src/core/linq/observable/transduce.js',
'src/core/anonymousobservable.js',
'src/core/autodetachobserver.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/headers/exports.js',
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js',
],
dest: 'dist/rx.compat.js'
},
lite: {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/liteheader.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
'src/core/internal/errors.js',
'src/core/headers/enumeratorheader.js',
'src/core/internal/bindcallback.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/internal/util.js',
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
'src/core/disposables/refcountdisposable.js',
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/internal/priorityqueue.js',
'src/core/notification.js',
'src/core/observer-lite.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
'src/core/observable.js',
'src/core/scheduledobserver.js',
'src/core/perf/observablebase.js',
'src/core/perf/operators/flatmapbase.js',
'src/core/enumerable.js',
// Creation
'src/core/perf/operators/toarray.js',
'src/core/linq/observable/create.js',
'src/core/linq/observable/defer.js',
'src/core/perf/operators/empty.js',
'src/core/perf/operators/from.js',
'src/core/perf/operators/fromarrayobservable.js','src/core/perf/operators/fromarray.js',
'src/core/perf/operators/never.js',
'src/core/perf/operators/of.js',
'src/core/perf/operators/pairs.js',
'src/core/perf/operators/range.js',
'src/core/perf/operators/repeat.js',
'src/core/perf/operators/just.js',
'src/core/perf/operators/throw.js',
// Multiple
'src/core/linq/observable/catchproto.js',
'src/core/linq/observable/catch.js',
'src/core/linq/observable/combinelatestproto.js',
'src/core/perf/operators/combinelatest.js',
'src/core/linq/observable/concatproto.js',
'src/core/perf/operators/concat.js',
'src/core/linq/observable/concatall.js',
'src/core/perf/operators/mergeconcat.js',
'src/core/linq/observable/merge.js',
'src/core/linq/observable/mergedelayerror.js',
'src/core/perf/operators/mergeall.js',
'src/core/perf/operators/skipuntil.js',
'src/core/perf/operators/switch.js',
'src/core/perf/operators/takeuntil.js',
'src/core/perf/operators/withlatestfrom.js',
'src/core/perf/operators/zip.js',
'src/core/linq/observable/zip.js',
'src/core/linq/observable/zipiterable.js',
// Single
'src/core/linq/observable/asobservable.js',
'src/core/linq/observable/dematerialize.js',
'src/core/perf/operators/distinctuntilchanged.js',
'src/core/perf/operators/tap.js',
'src/core/perf/operators/finally.js',
'src/core/perf/operators/ignoreelements.js',
'src/core/linq/observable/materialize.js',
'src/core/linq/observable/repeatproto.js',
'src/core/linq/observable/retry.js',
'src/core/linq/observable/retrywhen.js',
'src/core/linq/observable/repeatwhen.js',
'src/core/perf/operators/scan.js',
'src/core/linq/observable/skiplast.js',
'src/core/linq/observable/startwith.js',
'src/core/linq/observable/takelast.js',
// Standard Query Operators
'src/core/perf/operators/concatmap.js',
'src/core/perf/operators/map.js',
'src/core/linq/observable/pluck.js',
'src/core/perf/operators/flatmap.js',
'src/core/perf/operators/flatmaplatest.js',
'src/core/perf/operators/skip.js',
'src/core/linq/observable/skipwhile.js',
'src/core/perf/operators/take.js',
'src/core/linq/observable/takewhile.js',
'src/core/perf/operators/filter.js',
// Async Operators
'src/core/perf/operators/fromcallback.js',
'src/core/perf/operators/fromnodecallback.js',
'src/core/linq/observable/fromevent.js', // publish
'src/core/linq/observable/fromeventpattern.js', // publish
'src/core/perf/operators/frompromise.js', // AsyncSubject, asObservable
'src/core/linq/observable/topromise.js',
'src/core/linq/observable/startasync.js',
// Binding Operators
'src/core/linq/observable/multicast.js', // ConnectableObservable
'src/core/linq/observable/publish.js', // mulitcast, Subject
'src/core/linq/observable/share.js', // mulitcast, Subject, Reference counted
'src/core/linq/observable/publishlast.js', // multicast, AsyncSubject
'src/core/linq/observable/publishvalue.js', // multicast, BehaviorSubject
'src/core/linq/observable/sharevalue.js', // multicast, BehaviorSubject, Reference counted
'src/core/linq/observable/replay.js', // multicast, ReplaySubject
'src/core/linq/observable/sharereplay.js',
'src/core/linq/connectableobservable.js',
// Time operators
'src/core/linq/observable/_observabletimer.js', // AnonymousObservable
'src/core/linq/observable/_observabletimerdateandperiod.js', // AnonymousObservable, normalizeTime
'src/core/linq/observable/_observabletimertimespanandperiod.js', // AnonymousObservable, defer, _observabletimerdateandperiod
'src/core/linq/observable/interval.js', // timeoutScheduler, _observabletimertimespanandperiod
'src/core/linq/observable/timer.js', // timeoutScheduler, _observabletimerdate, _observabletimerdateandperiod, _observabletimertimespan, _observabletimertimespanandperiod
'src/core/linq/observable/delay.js', // AnonymousObservable, timeoutScheduler, SerialDisposable, materialize, timestamp
'src/core/linq/observable/debounce.js', // AnonymousObservable, SerialDisposable, timeoutScheduler, SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/timestamp.js', // timeoutScheduler, select
'src/core/linq/observable/sample.js', // AnonymousObservable, CompositeDisposable, interval, timeoutScheduler
'src/core/linq/observable/timeout.js', // AnonymousObservable, timeoutScheduler, throw, SingleAssignmentDisposable, SerialDisposable, CompositeDisposable
'src/core/linq/observable/throttle.js',
// Backpressure operators
'src/core/backpressure/pausable.js',
'src/core/backpressure/pausablebuffered.js',
'src/core/backpressure/controlled.js',
'src/core/linq/observable/pipe.js',
// Transducers
'src/core/linq/observable/transduce.js',
'src/core/anonymousobservable.js',
'src/core/autodetachobserver.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/subjects/behaviorsubject.js',
'src/core/subjects/replaysubject.js',
'src/core/backpressure/pauser.js',
'src/core/headers/exports.js',
// End long stack traces
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js',
],
dest: 'dist/rx.lite.js'
},
'lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/intro.js',
'src/core/headers/liteheader-compat.js',
// Stack trace start
'src/core/internal/trycatch.js',
'src/core/longstacktraces/longstackbegin.js',
'src/core/longstacktraces/longstacktraces.js',
'src/core/internal/polyfills.js',
'src/core/internal/errors.js',
'src/core/headers/enumeratorheader.js',
'src/core/internal/bindcallback.js',
'src/core/internal/dontenums.js',
'src/core/internal/isequal.js',
'src/core/internal/util.js',
'src/core/disposables/compositedisposable.js',
'src/core/disposables/disposable.js',
'src/core/disposables/booleandisposable.js',
'src/core/disposables/binarydisposable.js',
'src/core/disposables/refcountdisposable.js',
'src/core/concurrency/scheduleditem.js',
'src/core/concurrency/scheduler.js',
'src/core/concurrency/scheduler.recursive.js',
'src/core/concurrency/scheduler.periodic.js',
'src/core/concurrency/immediatescheduler.js',
'src/core/concurrency/currentthreadscheduler.js',
'src/core/concurrency/scheduleperiodicrecursive.js',
'src/core/concurrency/defaultscheduler.js',
'src/core/internal/priorityqueue.js',
'src/core/notification.js',
'src/core/observer-lite.js',
'src/core/abstractobserver.js',
'src/core/anonymousobserver.js',
'src/core/observable.js',
'src/core/perf/observablebase.js',
'src/core/perf/operators/flatmapbase.js',
'src/core/enumerable.js',
'src/core/scheduledobserver.js',
// Creation
'src/core/perf/operators/toarray.js',
'src/core/linq/observable/create.js',
'src/core/linq/observable/defer.js',
'src/core/perf/operators/empty.js',
'src/core/perf/operators/from.js',
'src/core/perf/operators/fromarrayobservable.js','src/core/perf/operators/fromarray.js',
'src/core/perf/operators/never.js',
'src/core/perf/operators/of.js',
'src/core/perf/operators/pairs.js',
'src/core/perf/operators/range.js',
'src/core/perf/operators/repeat.js',
'src/core/perf/operators/just.js',
'src/core/perf/operators/throw.js',
// Multiple
'src/core/linq/observable/catchproto.js',
'src/core/linq/observable/catch.js',
'src/core/linq/observable/combinelatestproto.js',
'src/core/perf/operators/combinelatest.js',
'src/core/linq/observable/concatproto.js',
'src/core/perf/operators/concat.js',
'src/core/linq/observable/concatall.js',
'src/core/perf/operators/mergeconcat.js',
'src/core/linq/observable/merge.js',
'src/core/perf/operators/mergeall.js',
'src/core/linq/observable/mergedelayerror.js',
'src/core/perf/operators/skipuntil.js',
'src/core/perf/operators/switch.js',
'src/core/perf/operators/takeuntil.js',
'src/core/perf/operators/withlatestfrom.js',
'src/core/perf/operators/zip.js',
'src/core/linq/observable/zip.js',
'src/core/linq/observable/zipiterable.js',
// Single
'src/core/linq/observable/asobservable.js',
'src/core/linq/observable/dematerialize.js',
'src/core/perf/operators/distinctuntilchanged.js',
'src/core/perf/operators/tap.js',
'src/core/perf/operators/finally.js',
'src/core/perf/operators/ignoreelements.js',
'src/core/linq/observable/materialize.js',
'src/core/linq/observable/repeatproto.js',
'src/core/linq/observable/retry.js',
'src/core/linq/observable/retrywhen.js',
'src/core/linq/observable/repeatwhen.js',
'src/core/perf/operators/scan.js',
'src/core/linq/observable/skiplast.js',
'src/core/linq/observable/startwith.js',
'src/core/linq/observable/takelast.js',
// Standard Query Operators
'src/core/perf/operators/concatmap.js',
'src/core/perf/operators/map.js',
'src/core/linq/observable/pluck.js',
'src/core/perf/operators/flatmap.js',
'src/core/perf/operators/flatmaplatest.js',
'src/core/perf/operators/skip.js',
'src/core/linq/observable/skipwhile.js',
'src/core/perf/operators/take.js',
'src/core/linq/observable/takewhile.js',
'src/core/perf/operators/filter.js',
// Async Operators
'src/core/perf/operators/fromcallback.js',
'src/core/perf/operators/fromnodecallback.js',
'src/core/linq/observable/fromevent.js', // publish
'src/core/linq/observable/fromeventpattern.js', // publish
'src/core/perf/operators/frompromise.js', // AsyncSubject, asObservable
'src/core/linq/observable/topromise.js',
'src/core/linq/observable/startasync.js',
// Binding Operators
'src/core/linq/observable/multicast.js', // ConnectableObservable
'src/core/linq/observable/publish.js', // mulitcast, Subject
'src/core/linq/observable/share.js', // mulitcast, Subject, Reference counted
'src/core/linq/observable/publishlast.js', // multicast, AsyncSubject
'src/core/linq/observable/publishvalue.js', // multicast, BehaviorSubject
'src/core/linq/observable/sharevalue.js', // multicast, BehaviorSubject, Reference counted
'src/core/linq/observable/replay.js', // multicast, ReplaySubject
'src/core/linq/observable/sharereplay.js',
'src/core/linq/connectableobservable.js',
// Time operators
'src/core/linq/observable/_observabletimer.js', // AnonymousObservable
'src/core/linq/observable/_observabletimerdateandperiod.js', // AnonymousObservable, normalizeTime
'src/core/linq/observable/_observabletimertimespanandperiod.js', // AnonymousObservable, defer, _observabletimerdateandperiod
'src/core/linq/observable/interval.js', // timeoutScheduler, _observabletimertimespanandperiod
'src/core/linq/observable/timer.js', // timeoutScheduler, _observabletimerdate, _observabletimerdateandperiod, _observabletimertimespan, _observabletimertimespanandperiod
'src/core/linq/observable/delay.js', // AnonymousObservable, timeoutScheduler, SerialDisposable, materialize, timestamp
'src/core/linq/observable/debounce.js', // AnonymousObservable, SerialDisposable, timeoutScheduler, SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/timestamp.js', // timeoutScheduler, select
'src/core/linq/observable/sample.js', // AnonymousObservable, CompositeDisposable, interval, timeoutScheduler
'src/core/linq/observable/timeout.js', // AnonymousObservable, timeoutScheduler, throw, SingleAssignmentDisposable, SerialDisposable, CompositeDisposable
'src/core/linq/observable/throttle.js',
// Backpressure operators
'src/core/backpressure/pausable.js',
'src/core/backpressure/pausablebuffered.js',
'src/core/backpressure/controlled.js',
'src/core/linq/observable/pipe.js',
// Transducers
'src/core/linq/observable/transduce.js',
'src/core/anonymousobservable.js',
'src/core/autodetachobserver.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/subject.js',
'src/core/subjects/asyncsubject.js',
'src/core/subjects/anonymoussubject.js',
'src/core/subjects/behaviorsubject.js',
'src/core/subjects/replaysubject.js',
'src/core/backpressure/pauser.js',
'src/core/headers/exports.js',
// End long stack traces
'src/core/longstacktraces/longstackend.js',
'src/core/headers/outro.js',
],
dest: 'dist/rx.lite.compat.js'
},
'lite-extras': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/liteextrasheader.js',
'src/core/internal/trycatch.js',
'src/core/disposables/scheduleddisposable.js',
'src/core/checkedobserver.js',
'src/core/observeonobserver.js',
'src/core/observer-extras.js',
// Concurrency
'src/core/linq/observable/observeon.js', // ObserveOnObserver
'src/core/linq/observable/subscribeon.js', // SingleAssignmentDisposable, SerialDisposable, ScheduleDisposable
// Creation
'src/core/linq/observable/generate.js',
'src/core/linq/observable/using.js',
// Multiple
'src/core/linq/observable/ambproto.js',
'src/core/linq/observable/amb.js',
'src/core/linq/observable/onerrorresumenextproto.js',
'src/core/linq/observable/onerrorresumenext.js',
// Single
'src/core/linq/observable/bufferwithcount.js',
'src/core/linq/observable/windowwithcount.js',
'src/core/linq/observable/takelastbuffer.js',
// Standard Query Operators
'src/core/linq/observable/defaultifempty.js',
'src/core/linq/observable/distinct.js',
'src/core/linq/observable/singleinstance.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.lite.extras.js'
},
'lite-extras-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/liteextrasheader.js',
'src/core/internal/trycatch.js',
'src/core/disposables/scheduleddisposable.js',
'src/core/checkedobserver.js',
'src/core/observeonobserver.js',
'src/core/observer-extras.js',
// Concurrency
'src/core/linq/observable/observeon.js', // ObserveOnObserver
'src/core/linq/observable/subscribeon.js', // SingleAssignmentDisposable, SerialDisposable, ScheduleDisposable
// Creation
'src/core/linq/observable/generate.js',
'src/core/linq/observable/using.js',
// Multiple
'src/core/linq/observable/ambproto.js',
'src/core/linq/observable/amb.js',
'src/core/linq/observable/onerrorresumenextproto.js',
'src/core/linq/observable/onerrorresumenext.js',
// Single
'src/core/linq/observable/bufferwithcount.js',
'src/core/linq/observable/windowwithcount.js',
'src/core/linq/observable/takelastbuffer.js',
// Standard Query Operators
'src/core/linq/observable/defaultifempty.js',
'src/core/linq/observable/distinct.js',
'src/core/linq/observable/singleinstance.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.lite.extras.compat.js'
},
backpressure: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/backpressureheader.js',
'src/core/internal/trycatch.js',
// Backpressure operators
'src/core/backpressure/pauser.js',
'src/core/backpressure/pausable.js',
'src/core/backpressure/pausablebuffered.js',
'src/core/backpressure/controlled.js',
'src/core/backpressure/stopandwait.js',
'src/core/backpressure/windowed.js',
'src/core/linq/observable/pipe.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.backpressure.js'
},
'backpressure-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/backpressureheader.js',
'src/core/internal/trycatch.js',
// Backpressure operators
'src/core/backpressure/stopandwait.js',
'src/core/backpressure/windowed.js',
'src/core/linq/observable/pipe.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-backpressure/rx.lite.backpressure.js'
},
'backpressure-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/backpressureheader.js',
'src/core/internal/trycatch.js',
// Backpressure operators
'src/core/backpressure/stopandwait.js',
'src/core/backpressure/windowed.js',
'src/core/linq/observable/pipe.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-backpressure-compat/rx.lite.backpressure.compat.js'
},
aggregates: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/aggregatesheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/_extremaby.js',
'src/core/linq/observable/_firstonly.js',
'src/core/perf/operators/reduce.js', // scan, startwith, finalvalue
'src/core/linq/observable/some.js', // where
'src/core/linq/observable/isempty.js', // any, select
'src/core/linq/observable/every.js', // where, any
'src/core/linq/observable/includes.js', // where, any
'src/core/linq/observable/count.js', // where, aggregate
'src/core/linq/observable/indexof.js',
'src/core/linq/observable/sum.js', // select, aggregate
'src/core/linq/observable/minby.js', // _extremaby
'src/core/linq/observable/min.js', // minby, _firstonly
'src/core/linq/observable/maxby.js', // _extremaby
'src/core/linq/observable/max.js', // max, _firstonly
'src/core/linq/observable/average.js', // select, scan, aggregate, finalvalue
'src/core/linq/observable/sequenceequal.js', // compositedisposable
'src/core/linq/observable/elementat.js',
'src/core/linq/observable/single.js',
'src/core/linq/observable/first.js',
'src/core/linq/observable/last.js',
'src/core/linq/observable/_findvalue.js',
'src/core/linq/observable/find.js', // _findvalue, where
'src/core/linq/observable/findindex.js', // _findvalue, where
'src/core/linq/observable/toset.js',
'src/core/linq/observable/tomap.js',
'src/core/linq/observable/slice.js',
'src/core/linq/observable/lastindexof.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.aggregates.js'
},
'aggregates-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/aggregatesheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/_extremaby.js',
'src/core/linq/observable/_firstonly.js',
'src/core/perf/operators/reduce.js', // scan, startwith, finalvalue
'src/core/linq/observable/some.js', // where
'src/core/linq/observable/isempty.js', // any, select
'src/core/linq/observable/every.js', // where, any
'src/core/linq/observable/includes.js', // where, any
'src/core/linq/observable/count.js', // where, aggregate
'src/core/linq/observable/indexof.js',
'src/core/linq/observable/sum.js', // select, aggregate
'src/core/linq/observable/minby.js', // _extremaby
'src/core/linq/observable/min.js', // minby, _firstonly
'src/core/linq/observable/maxby.js', // _extremaby
'src/core/linq/observable/max.js', // max, _firstonly
'src/core/linq/observable/average.js', // select, scan, aggregate, finalvalue
'src/core/linq/observable/sequenceequal.js', // compositedisposable
'src/core/linq/observable/elementat.js',
'src/core/linq/observable/single.js',
'src/core/linq/observable/first.js',
'src/core/linq/observable/last.js',
'src/core/linq/observable/_findvalue.js',
'src/core/linq/observable/find.js', // _findvalue, where
'src/core/linq/observable/findindex.js', // _findvalue, where
'src/core/linq/observable/toset.js',
'src/core/linq/observable/tomap.js',
'src/core/linq/observable/slice.js',
'src/core/linq/observable/lastindexof.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-aggregates/rx.lite.aggregates.js'
},
'aggregates-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/aggregatesheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/_extremaby.js',
'src/core/linq/observable/_firstonly.js',
'src/core/perf/operators/reduce.js', // scan, startwith, finalvalue
'src/core/linq/observable/some.js', // where
'src/core/linq/observable/isempty.js', // any, select
'src/core/linq/observable/every.js', // where, any
'src/core/linq/observable/includes.js', // where, any
'src/core/linq/observable/count.js', // where, aggregate
'src/core/linq/observable/indexof.js',
'src/core/linq/observable/sum.js', // select, aggregate
'src/core/linq/observable/minby.js', // _extremaby
'src/core/linq/observable/min.js', // minby, _firstonly
'src/core/linq/observable/maxby.js', // _extremaby
'src/core/linq/observable/max.js', // max, _firstonly
'src/core/linq/observable/average.js', // select, scan, aggregate, finalvalue
'src/core/linq/observable/sequenceequal.js', // compositedisposable
'src/core/linq/observable/elementat.js',
'src/core/linq/observable/single.js',
'src/core/linq/observable/first.js',
'src/core/linq/observable/last.js',
'src/core/linq/observable/_findvalue.js',
'src/core/linq/observable/find.js', // _findvalue, where
'src/core/linq/observable/findindex.js', // _findvalue, where
'src/core/linq/observable/toset.js',
'src/core/linq/observable/tomap.js',
'src/core/linq/observable/slice.js',
'src/core/linq/observable/lastindexof.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-aggregates-compat/rx.lite.aggregates.compat.js'
},
'async': {
src: [
'src/core/headers/license.js',
'src/core/headers/asyncintro.js',
'src/core/headers/asyncheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/spawn.js',
'src/core/linq/observable/start.js', // toasync
'src/core/linq/observable/toasync.js', // AsyncSubject, asObservable
'src/core/perf/operators/fromcallback.js',
'src/core/perf/operators/fromnodecallback.js',
'src/core/linq/observable/fromevent.js', // publish
'src/core/linq/observable/fromeventpattern.js', // publish
'src/core/linq/observable/startasync.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.async.js'
},
'async-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/asyncintro.js',
'src/core/headers/asyncheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/spawn.js',
'src/core/linq/observable/start.js', // toasync
'src/core/linq/observable/toasync.js', // asyncsubject, asObservable
'src/core/perf/operators/fromcallback.js',
'src/core/perf/operators/fromnodecallback.js',
'src/core/linq/observable/fromevent.js', // publish
'src/core/linq/observable/fromeventpattern.js', // publish
'src/core/linq/observable/startasync.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.async.compat.js'
},
'async-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/asyncheader.js',
'src/core/linq/observable/spawn.js',
'src/core/linq/observable/start.js', // toasync
'src/core/linq/observable/startasync.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-async/rx.lite.async.js'
},
'async-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/asyncheader.js',
'src/core/linq/observable/spawn.js',
'src/core/linq/observable/start.js', // toasync
'src/core/linq/observable/startasync.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-async-compat/rx.lite.async.compat.js'
},
binding: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/bindingheader.js',
'src/core/linq/observable/multicast.js', // ConnectableObservable
'src/core/linq/observable/publish.js', // mulitcast, Subject
'src/core/linq/observable/share.js', // mulitcast, Subject, Reference counted
'src/core/linq/observable/publishlast.js', // multicast, AsyncSubject
'src/core/linq/observable/publishvalue.js', // multicast, BehaviorSubject
'src/core/linq/observable/sharevalue.js', // multicast, BehaviorSubject, Reference counted
'src/core/linq/observable/replay.js', // multicast, ReplaySubject
'src/core/linq/observable/sharereplay.js',
'src/core/subjects/innersubscription.js',
'src/core/subjects/behaviorsubject.js',
'src/core/subjects/replaysubject.js',
'src/core/linq/connectableobservable.js',
'src/core/linq/observable/singleinstance.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.binding.js'
},
coincidence: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/coincidenceheader.js',
'src/core/internal/trycatch.js',
'src/core/internal/map.js',
'src/core/linq/observable/join.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/groupjoin.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/buffer.js', // window, selectMany, toArray
'src/core/linq/observable/window.js', // CompositeDisposable, RefCountDisposable, Subject, SingleAssignmentDisposable
'src/core/linq/observable/pairwise.js',
'src/core/linq/observable/partition.js',
'src/core/linq/observable/groupby.js',
'src/core/linq/observable/groupbyuntil.js',
'src/core/linq/groupedobservable.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.coincidence.js'
},
'coincidence-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/coincidenceheader.js',
'src/core/internal/trycatch.js',
'src/core/internal/map.js',
'src/core/linq/observable/join.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/groupjoin.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/buffer.js', // window, selectMany, toArray
'src/core/linq/observable/window.js', // CompositeDisposable, RefCountDisposable, Subject, SingleAssignmentDisposable
'src/core/linq/observable/pairwise.js',
'src/core/linq/observable/partition.js',
'src/core/linq/observable/groupby.js',
'src/core/linq/observable/groupbyuntil.js',
'src/core/linq/groupedobservable.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-coincidence/rx.lite.coincidence.js'
},
'coincidence-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/coincidenceheader.js',
'src/core/internal/trycatch.js',
'src/core/internal/map.js',
'src/core/linq/observable/join.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/groupjoin.js', // SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, Dictionary
'src/core/linq/observable/buffer.js', // window, selectMany, toArray
'src/core/linq/observable/window.js', // CompositeDisposable, RefCountDisposable, Subject, SingleAssignmentDisposable
'src/core/linq/observable/pairwise.js',
'src/core/linq/observable/partition.js',
'src/core/linq/observable/groupby.js',
'src/core/linq/observable/groupbyuntil.js',
'src/core/linq/groupedobservable.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-coincidence-compat/rx.lite.coincidence.compat.js'
},
experimental: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/experimentalheader.js',
'src/core/internal/trycatch.js',
'src/core/headers/enumeratorheader.js',
'src/core/linq/enumerable/while.js', // Enumerable
'src/core/linq/observable/let.js',
'src/core/linq/observable/if.js', // defer, empty
'src/core/linq/observable/for.js', // Enumerable.forEach, concatproto
'src/core/linq/observable/while.js', // Enumerable.while, concatproto
'src/core/linq/observable/dowhile.js', // Enumerable.while, concat
'src/core/linq/observable/case.js', // defer, empty
'src/core/linq/observable/expand.js', // immediateScheduler, SerialDisposable, CompositeDisposable, SingleAssignmentDisposable
'src/core/linq/observable/forkjoin.js', // CompositeDisposable
'src/core/linq/observable/forkjoinproto.js', // SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/manyselect.js', // ImmediateScheduler, CurrentThreadScheduler, select, do, observeOn
// Experimental Flattening
'src/core/linq/observable/switchfirst.js',
'src/core/perf/operators/flatmapfirst.js',
'src/core/perf/operators/flatmapwithmaxconcurrent.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.experimental.js'
},
'experimental-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/experimentalheader.js',
'src/core/internal/trycatch.js',
'src/core/headers/enumeratorheader.js',
'src/core/linq/enumerable/while.js', // Enumerable
'src/core/linq/observable/let.js',
'src/core/linq/observable/if.js', // defer, empty
'src/core/linq/observable/for.js', // Enumerable.forEach, concatproto
'src/core/linq/observable/while.js', // Enumerable.while, concatproto
'src/core/linq/observable/dowhile.js', // Enumerable.while, concat
'src/core/linq/observable/case.js', // defer, empty
'src/core/linq/observable/expand.js', // immediateScheduler, SerialDisposable, CompositeDisposable, SingleAssignmentDisposable
'src/core/linq/observable/forkjoin.js', // CompositeDisposable
'src/core/linq/observable/forkjoinproto.js', // SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/manyselect.js', // ImmediateScheduler, CurrentThreadScheduler, select, do, observeOn
// Experimental Flattening
'src/core/linq/observable/switchfirst.js',
'src/core/perf/operators/flatmapfirst.js',
'src/core/perf/operators/flatmapwithmaxconcurrent.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-experimental/rx.lite.experimental.js'
},
'experimental-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/experimentalheader.js',
'src/core/internal/trycatch.js',
'src/core/headers/enumeratorheader.js',
'src/core/linq/enumerable/while.js', // Enumerable
'src/core/linq/observable/let.js',
'src/core/linq/observable/if.js', // defer, empty
'src/core/linq/observable/for.js', // Enumerable.forEach, concatproto
'src/core/linq/observable/while.js', // Enumerable.while, concatproto
'src/core/linq/observable/dowhile.js', // Enumerable.while, concat
'src/core/linq/observable/case.js', // defer, empty
'src/core/linq/observable/expand.js', // immediateScheduler, SerialDisposable, CompositeDisposable, SingleAssignmentDisposable
'src/core/linq/observable/forkjoin.js', // CompositeDisposable
'src/core/linq/observable/forkjoinproto.js', // SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/manyselect.js', // ImmediateScheduler, CurrentThreadScheduler, select, do, observeOn
// Experimental Flattening
'src/core/linq/observable/switchfirst.js',
'src/core/perf/operators/flatmapfirst.js',
'src/core/perf/operators/flatmapwithmaxconcurrent.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-experimental-compat/rx.lite.experimental.compat.js'
},
joinpatterns: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/joinpatternsheader.js',
'src/core/internal/trycatch.js',
'src/core/internal/map.js',
'src/core/joins/pattern.js',
'src/core/joins/plan.js',
'src/core/joins/activeplan.js',
'src/core/joins/joinobserver.js',
'src/core/linq/observable/and.js', // Pattern
'src/core/linq/observable/thendo.js', // Pattern
'src/core/linq/observable/when.js', // CompositeDisposable
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.joinpatterns.js'
},
'joinpatterns-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/joinpatternsheader.js',
'src/core/internal/trycatch.js',
'src/core/internal/map.js',
'src/core/joins/pattern.js',
'src/core/joins/plan.js',
'src/core/joins/activeplan.js',
'src/core/joins/joinobserver.js',
'src/core/linq/observable/and.js', // Pattern
'src/core/linq/observable/thendo.js', // Pattern
'src/core/linq/observable/when.js', // CompositeDisposable
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-joinpatterns/rx.lite.joinpatterns.js'
},
'joinpatterns-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/joinpatternsheader.js',
'src/core/internal/trycatch.js',
'src/core/internal/map.js',
'src/core/joins/pattern.js',
'src/core/joins/plan.js',
'src/core/joins/activeplan.js',
'src/core/joins/joinobserver.js',
'src/core/linq/observable/and.js', // Pattern
'src/core/linq/observable/thendo.js', // Pattern
'src/core/linq/observable/when.js', // CompositeDisposable
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-joinpatterns-compat/rx.lite.joinpatterns.compat.js'
},
testing: {
src: [
'src/core/headers/license.js',
'src/core/headers/testintro.js',
'src/core/headers/testheader.js',
'src/core/testing/reactivetest.js',
'src/core/testing/recorded.js',
'src/core/testing/subscription.js',
'src/core/testing/mockdisposable.js',
'src/core/testing/mockobserver.js',
'src/core/testing/mockpromise.js',
'src/core/testing/hotobservable.js',
'src/core/testing/coldobservable.js',
'src/core/testing/testscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.testing.js'
},
'testing-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/litetestintro.js',
'src/core/headers/testheader.js',
'src/core/testing/reactivetest.js',
'src/core/testing/recorded.js',
'src/core/testing/subscription.js',
'src/core/testing/mockdisposable.js',
'src/core/testing/mockobserver.js',
'src/core/testing/mockpromise.js',
'src/core/testing/hotobservable.js',
'src/core/testing/coldobservable.js',
'src/core/testing/testscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-testing/rx.lite.testing.js'
},
'testing-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/litetestintro-compat.js',
'src/core/headers/testheader.js',
'src/core/testing/reactivetest.js',
'src/core/testing/recorded.js',
'src/core/testing/subscription.js',
'src/core/testing/mockdisposable.js',
'src/core/testing/mockobserver.js',
'src/core/testing/mockpromise.js',
'src/core/testing/hotobservable.js',
'src/core/testing/coldobservable.js',
'src/core/testing/testscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-testing-compat/rx.lite.testing.compat.js'
},
time: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/timeheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/_observabletimer.js', // AnonymousObservable
'src/core/linq/observable/_observabletimerdateandperiod.js', // AnonymousObservable, normalizeTime
'src/core/linq/observable/_observabletimertimespanandperiod.js', // AnonymousObservable, defer, _observabletimerdateandperiod
'src/core/linq/observable/interval.js', // timeoutScheduler, _observabletimertimespanandperiod
'src/core/linq/observable/timer.js', // timeoutScheduler, _observabletimerdate, _observabletimerdateandperiod, _observabletimertimespan, _observabletimertimespanandperiod
'src/core/linq/observable/delay.js', // AnonymousObservable, timeoutScheduler, SerialDisposable, materialize, timestamp
'src/core/linq/observable/debounce.js', // AnonymousObservable, SerialDisposable, timeoutScheduler, SingleAssignmentDisposable, CompositeDisposable
'src/core/linq/observable/windowwithtime.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/windowwithtimeorcount.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/bufferwithtime.js', // windowwithtime, selectMany, toArray
'src/core/linq/observable/bufferwithtimeorcount.js', // windowwithtimeorcount, selectMany, toArray
'src/core/linq/observable/timeinterval.js', // timeoutScheduler, defer, select
'src/core/linq/observable/timestamp.js', // timeoutScheduler, select
'src/core/linq/observable/sample.js', // AnonymousObservable, CompositeDisposable, interval, timeoutScheduler
'src/core/linq/observable/timeout.js', // AnonymousObservable, timeoutScheduler, throw, SingleAssignmentDisposable, SerialDisposable, CompositeDisposable
'src/core/linq/observable/generatewithabsolutetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/generatewithrelativetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/delaysubscription.js', // delayWithSelector, timer, empty
'src/core/linq/observable/skiplastwithtime.js',
'src/core/linq/observable/takelastwithtime.js',
'src/core/linq/observable/takelastbufferwithtime.js',
'src/core/linq/observable/takewithtime.js',
'src/core/linq/observable/skipwithtime.js',
'src/core/linq/observable/skipuntilwithtime.js',
'src/core/linq/observable/takeuntilwithtime.js',
'src/core/linq/observable/throttle.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.time.js'
},
'time-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/timeheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/windowwithtime.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/windowwithtimeorcount.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/bufferwithtime.js', // windowwithtime, selectMany, toArray
'src/core/linq/observable/bufferwithtimeorcount.js', // windowwithtimeorcount, selectMany, toArray
'src/core/linq/observable/timeinterval.js', // timeoutScheduler, defer, select
'src/core/linq/observable/generatewithabsolutetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/generatewithrelativetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/delaysubscription.js', // delayWithSelector, timer, empty
'src/core/linq/observable/skiplastwithtime.js',
'src/core/linq/observable/takelastwithtime.js',
'src/core/linq/observable/takelastbufferwithtime.js',
'src/core/linq/observable/takewithtime.js',
'src/core/linq/observable/skipwithtime.js',
'src/core/linq/observable/skipuntilwithtime.js',
'src/core/linq/observable/takeuntilwithtime.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-time/rx.lite.time.js'
},
'time-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/timeheader.js',
'src/core/internal/trycatch.js',
'src/core/linq/observable/windowwithtime.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/windowwithtimeorcount.js', // AnonymousObservable, SerialDisposable, SingleAssignmentDisposable, RefCountDisposable, CompositeDisposable, addref, subject
'src/core/linq/observable/bufferwithtime.js', // windowwithtime, selectMany, toArray
'src/core/linq/observable/bufferwithtimeorcount.js', // windowwithtimeorcount, selectMany, toArray
'src/core/linq/observable/timeinterval.js', // timeoutScheduler, defer, select
'src/core/linq/observable/generatewithabsolutetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/generatewithrelativetime.js', // timeoutScheduler, AnonymousObservable
'src/core/linq/observable/delaysubscription.js', // delayWithSelector, timer, empty
'src/core/linq/observable/skiplastwithtime.js',
'src/core/linq/observable/takelastwithtime.js',
'src/core/linq/observable/takelastbufferwithtime.js',
'src/core/linq/observable/takewithtime.js',
'src/core/linq/observable/skipwithtime.js',
'src/core/linq/observable/skipuntilwithtime.js',
'src/core/linq/observable/takeuntilwithtime.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-time-compat/rx.lite.time.compat.js'
},
virtualtime: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/virtualtimeheader.js',
'src/core/concurrency/virtualtimescheduler.js',
'src/core/concurrency/historicalscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.virtualtime.js'
},
'virtualtime-lite': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro.js',
'src/core/headers/virtualtimeheader.js',
'src/core/concurrency/virtualtimescheduler.js',
'src/core/concurrency/historicalscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-virtualtime/rx.lite.virtualtime.js'
},
'virtualtime-lite-compat': {
src: [
'src/core/headers/license.js',
'src/core/headers/liteintro-compat.js',
'src/core/headers/virtualtimeheader.js',
'src/core/concurrency/virtualtimescheduler.js',
'src/core/concurrency/historicalscheduler.js',
'src/core/headers/suboutro.js'
],
dest: 'modules/rx-lite-virtualtime-compat/rx.lite.virtualtime.compat.js'
},
sorting: {
src: [
'src/core/headers/license.js',
'src/core/headers/subintro.js',
'src/core/headers/sortingheader.js',
'src/core/linq/observable/jortsort.js',
'src/core/linq/observable/jortsortuntil.js',
'src/core/headers/suboutro.js'
],
dest: 'dist/rx.sorting.js'
}
},
uglify: {
options: {
banner:
'/* Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.*/'
},
core: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.core.map'
},
files: {'dist/rx.core.min.js': ['dist/rx.core.js'] }
},
'core-binding': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.core.binding.map'
},
files: {'dist/rx.core.binding.min.js': ['dist/rx.core.binding.js'] }
},
'core-testing': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.core.testing.map'
},
files: {'dist/rx.core.testing.min.js': ['dist/rx.core.testing.js'] }
},
all: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.all.map'
},
files: {'dist/rx.all.min.js': ['dist/rx.all.js'] }
},
'all-compat': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.all.compat.map'
},
files: {'dist/rx.all.compat.min.js': ['dist/rx.all.compat.js'] }
},
main: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.map'
},
files: {'dist/rx.min.js': ['dist/rx.js'] }
},
'main-compat': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.compat.map'
},
files: {'dist/rx.compat.min.js': ['dist/rx.compat.js'] }
},
lite: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.lite.map'
},
files: {'dist/rx.lite.min.js': ['dist/rx.lite.js'] }
},
'lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.lite.compat.map'
},
files: {'dist/rx.lite.compat.min.js': ['dist/rx.lite.compat.js'] }
},
'lite-extras': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.lite.extras.map'
},
files: {'dist/rx.lite.extras.min.js': ['dist/rx.lite.extras.js'] }
},
'lite-extras-compat': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.lite.extras.compat.map'
},
files: {'dist/rx.lite.extras.compat.min.js': ['dist/rx.lite.extras.compat.js'] }
},
aggregates: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.aggregates.map'
},
files: {'dist/rx.aggregates.min.js': ['dist/rx.aggregates.js'] }
},
'aggregates-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-aggregates/rx.lite.aggregates.map'
},
files: {'modules/rx-lite-aggregates/rx.lite.aggregates.min.js': ['modules/rx-lite-aggregates/rx.lite.aggregates.js'] }
},
'aggregates-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-aggregates-compat/rx.lite.aggregates.compat.map'
},
files: {'modules/rx-lite-aggregates-compat/rx.lite.aggregates.compat.min.js': ['modules/rx-lite-aggregates-compat/rx.lite.aggregates.compat.js'] }
},
'async': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.async.map'
},
files: {'dist/rx.async.min.js': ['dist/rx.async.js'] }
},
'async-compat': {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.async.compat.map'
},
files: {'dist/rx.async.compat.min.js': ['dist/rx.async.compat.js'] }
},
'async-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-async/rx.lite.async.map'
},
files: {'modules/rx-lite-async/rx.lite.async.min.js': ['modules/rx-lite-async/rx.lite.async.js'] }
},
'async-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-async-compat/rx.lite.async.compat.map'
},
files: {'modules/rx-lite-async-compat/rx.lite.async.compat.min.js': ['modules/rx-lite-async-compat/rx.lite.async.compat.js'] }
},
backpressure: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.backpressure.map'
},
files: {'dist/rx.backpressure.min.js': ['dist/rx.backpressure.js'] }
},
'backpressure-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-backpressure/rx.lite.backpressure.map'
},
files: {'modules/rx-lite-backpressure/rx.lite.backpressure.min.js': ['modules/rx-lite-backpressure/rx.lite.backpressure.js'] }
},
'backpressure-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-backpressure-compat/rx.lite.backpressure.compat.map'
},
files: {'modules/rx-lite-backpressure-compat/rx.lite.backpressure.compat.min.js': ['modules/rx-lite-backpressure-compat/rx.lite.backpressure.compat.js'] }
},
binding: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.binding.map'
},
files: {'dist/rx.binding.min.js': ['dist/rx.binding.js'] }
},
coincidence: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.coincidence.map'
},
files: {'dist/rx.coincidence.min.js': ['dist/rx.coincidence.js'] }
},
'coincidence-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-coincidence/rx.lite.coincidence.map'
},
files: {'modules/rx-lite-coincidence/rx.lite.coincidence.min.js': ['modules/rx-lite-coincidence/rx.lite.coincidence.js'] }
},
'coincidence-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-coincidence-compat/rx.lite.coincidence.compat.map'
},
files: {'modules/rx-lite-coincidence-compat/rx.lite.coincidence.compat.min.js': ['modules/rx-lite-coincidence-compat/rx.lite.coincidence.compat.js'] }
},
experimental: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.experimental.map'
},
files: {'dist/rx.experimental.min.js': ['dist/rx.experimental.js'] }
},
'experimental-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-experimental/rx.lite.experimental.map'
},
files: {'modules/rx-lite-experimental/rx.lite.experimental.min.js': ['modules/rx-lite-experimental/rx.lite.experimental.js'] }
},
'experimental-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-experimental-compat/rx.lite.experimental.compat.map'
},
files: {'modules/rx-lite-experimental-compat/rx.lite.experimental.compat.min.js': ['modules/rx-lite-experimental-compat/rx.lite.experimental.compat.js'] }
},
joinpatterns: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.joinpatterns.map'
},
files: {'dist/rx.joinpatterns.min.js': ['dist/rx.joinpatterns.js'] }
},
'joinpatterns-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-joinpatterns/rx.lite.joinpatterns.map'
},
files: {'modules/rx-lite-joinpatterns/rx.lite.joinpatterns.min.js': ['modules/rx-lite-joinpatterns/rx.lite.joinpatterns.js'] }
},
'joinpatterns-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-joinpatterns-compat/rx.lite.joinpatterns.compat.map'
},
files: {'modules/rx-lite-joinpatterns-compat/rx.lite.joinpatterns.compat.min.js': ['modules/rx-lite-joinpatterns-compat/rx.lite.joinpatterns.compat.js'] }
},
testing: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.testing.map'
},
files: {'dist/rx.testing.min.js': ['dist/rx.testing.js'] }
},
'testing-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-testing/rx.lite.testing.map'
},
files: {'modules/rx-lite-testing/rx.lite.testing.min.js': ['modules/rx-lite-testing/rx.lite.testing.js'] }
},
'testing-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-testing-compat/rx.lite.testing.compat.map'
},
files: {'modules/rx-lite-testing-compat/rx.lite.testing.compat.min.js': ['modules/rx-lite-testing-compat/rx.lite.testing.compat.js'] }
},
time: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.time.map'
},
files: {'dist/rx.time.min.js': ['dist/rx.time.js'] }
},
'time-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-time/rx.lite.time.map'
},
files: {'modules/rx-lite-time/rx.lite.time.min.js': ['modules/rx-lite-time/rx.lite.time.js'] }
},
'time-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-time-compat/rx.lite.time.compat.map'
},
files: {'modules/rx-lite-time-compat/rx.lite.time.compat.min.js': ['modules/rx-lite-time-compat/rx.lite.time.compat.js'] }
},
virtualtime: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.virtualtime.map'
},
files: {'dist/rx.virtualtime.min.js': ['dist/rx.virtualtime.js'] }
},
'virtualtime-lite': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-virtualtime/rx.lite.virtualtime.map'
},
files: {'modules/rx-lite-virtualtime/rx.lite.virtualtime.min.js': ['modules/rx-lite-virtualtime/rx.lite.virtualtime.js'] }
},
'virtualtime-lite-compat': {
options: {
sourceMap: true,
sourceMapName: 'modules/rx-lite-virtualtime-compat/rx.lite.virtualtime.compat.map'
},
files: {'modules/rx-lite-virtualtime-compat/rx.lite.virtualtime.compat.min.js': ['modules/rx-lite-virtualtime-compat/rx.lite.virtualtime.compat.js'] }
},
sorting: {
options: {
sourceMap: true,
sourceMapName: 'dist/rx.sorting.map'
},
files: {'dist/rx.sorting.min.js': ['dist/rx.sorting.js'] }
}
},
qunit: {
all: ['tests/*.html']
},
jshint: {
all: [
'rx.all.js'
]
},
jscs: {
src: 'src/**/*.js',
options: {
config: '.jscsrc'
}
},
watch: {
scripts: {
files: 'src/**/*.js',
tasks: ['default'],
options: {
interrupt: true
}
}
},
copy: {
'lite': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.lite.js',
'dist/rx.lite.map',
'dist/rx.lite.min.js'
],
dest: 'modules/rx-lite/'
},
'lite-compat': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.lite.compat.js',
'dist/rx.lite.compat.map',
'dist/rx.lite.compat.min.js'
],
dest: 'modules/rx-lite-compat/'
},
'lite-extras': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.lite.extras.js',
'dist/rx.lite.extras.map',
'dist/rx.lite.extras.min.js'
],
dest: 'modules/rx-lite-extras/'
},
'lite-extras-compat': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.lite.extras.compat.js',
'dist/rx.lite.extras.compat.map',
'dist/rx.lite.extras.compat.min.js'
],
dest: 'modules/rx-lite-extras-compat/'
},
'core': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.core.js',
'dist/rx.core.map',
'dist/rx.core.min.js'
],
dest: 'modules/rx-core/'
},
'core-binding': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.core.binding.js',
'dist/rx.core.binding.map',
'dist/rx.core.binding.min.js'
],
dest: 'modules/rx-core-binding/'
},
'core-testing': {
flatten: true,
filter: 'isFile',
expand: true,
src: [
'dist/rx.core.testing.js',
'dist/rx.core.testing.map',
'dist/rx.core.testing.min.js'
],
dest: 'modules/rx-core-testing/'
}
}
});
// Load all "grunt-*" tasks
require('load-grunt-tasks')(grunt);
function createNuGetPackage(nuspec) {
var done = this.async();
//invoke nuget.exe
grunt.util.spawn({
cmd: ".nuget/nuget.exe",
args: [
//specify the .nuspec file
"pack",
nuspec,
//specify where we want the package to be created
"-OutputDirectory",
"nuget",
//override the version with whatever is currently defined in package.json
"-Version",
grunt.config.get("pkg").version
]
}, function (error, result) {
if (error) {
grunt.log.error(error);
} else {
grunt.log.write(result);
}
done();
});
}
grunt.registerTask('nuget-complete', 'Register NuGet-Complete', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Complete/RxJS-Complete.nuspec');
});
grunt.registerTask('nuget-aggregates', 'Register NuGet-Aggregates', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Aggregates/RxJS-Aggregates.nuspec');
});
grunt.registerTask('nuget-all', 'Register NuGet-All', function () {
createNuGetPackage.call(this, 'nuget/RxJS-All/RxJS-All.nuspec');
});
grunt.registerTask('nuget-async', 'Register NuGet-Async', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Async/RxJS-Async.nuspec');
});
grunt.registerTask('nuget-backpressure', 'Register NuGet-BackPressure', function () {
createNuGetPackage.call(this, 'nuget/RxJS-BackPressure/RxJS-BackPressure.nuspec');
});
grunt.registerTask('nuget-binding', 'Register NuGet-Binding', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Binding/RxJS-Binding.nuspec');
});
grunt.registerTask('nuget-coincidence', 'Register NuGet-Coincidence', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Coincidence/RxJS-Coincidence.nuspec');
});
grunt.registerTask('nuget-experimental', 'Register NuGet-Experimental', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Experimental/RxJS-Experimental.nuspec');
});
grunt.registerTask('nuget-joinpatterns', 'Register NuGet-JoinPatterns', function () {
createNuGetPackage.call(this, 'nuget/RxJS-JoinPatterns/RxJS-JoinPatterns.nuspec');
});
grunt.registerTask('nuget-lite', 'Register NuGet-Lite', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Lite/RxJS-Lite.nuspec');
});
grunt.registerTask('nuget-main', 'Register NuGet-Main', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Main/RxJS-Main.nuspec');
});
grunt.registerTask('nuget-testing', 'Register NuGet-Testing', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Testing/RxJS-Testing.nuspec');
});
grunt.registerTask('nuget-time', 'Register NuGet-Time', function () {
createNuGetPackage.call(this, 'nuget/RxJS-Time/RxJS-Time.nuspec');
});
grunt.registerTask('nuget-virtualtime', 'Register NuGet-VirtualTime', function () {
createNuGetPackage.call(this, 'nuget/RxJS-VirtualTime/RxJS-VirtualTime.nuspec');
});
grunt.registerTask('nuget', [
'nuget-complete',
'nuget-aggregates',
'nuget-all',
'nuget-async',
'nuget-backpressure',
'nuget-binding',
'nuget-coincidence',
'nuget-experimental',
'nuget-joinpatterns',
'nuget-lite',
'nuget-main',
'nuget-testing',
'nuget-time',
'nuget-virtualtime'
]);
grunt.registerTask('rebuild-ts', 'Rebuild typescript declarations', function() {
var path = require('path');
var fs = require('fs');
var cache = {};
var dependencies = {};
var concatItems = grunt.config.get('concat');
var allLoadedFiles = {};
function loadFile(tsFile) {
if (cache[tsFile]) {
return;
}
var dependencyRegex = /\/\/\/ /g;
var c; //, count = 0;
var source = grunt.file.read(tsFile);
// source with tests
var s = source.match(/module Rx \{([\s\S]*)\}[\s\S]*\(function\s*\(\)\s*\{[\s\S]*\}\)/);
if (s && s[1]) {
c = cache[tsFile] = s[1];
}
if (!s) {
// source without tests
s = source.match(/module Rx \{([\s\S]*)\}/);
if (s && s[1]) {
c = cache[tsFile] = s[1];
}
}
var deps = dependencies[tsFile] = [];
var result;
while (result = dependencyRegex.exec(source)) {
var dep = path.resolve(__dirname, path.dirname(tsFile), result[1])
.substr(__dirname.length + 1)
.replace(/\\/g, '/');
if (tsFile.indexOf('/testscheduler.ts') > -1 && dep.indexOf('virtualtimescheduler.ts') > -1) {
continue;
}
deps.push(dep);
loadFile(dep);
}
return c;
}
function addLoadedFile(concatKey, tsFile) {
if (loadedFiles[tsFile]) {
return;
}
if (!(concatKey === 'all' || concatKey === 'main' || concatKey === 'lite' || concatKey === 'core')) {
if ((concatKey.indexOf('lite') === 0 && allLoadedFiles['lite'][tsFile])
|| (concatKey.indexOf('lite') !== 0 && allLoadedFiles['main'][tsFile])
|| allLoadedFiles['core'][tsFile]) {
loadedFiles[tsFile] = true;
return;
}
}
if (!(tsFile.match(/\/toset\.ts$/) || tsFile.match(/\/tomap\.ts$/))) {
output.push(cache[tsFile]);
}
es6Output.push(cache[tsFile]);
loadedFiles[tsFile] = true;
}
function addFileContent(concatKey, tsFile) {
if (loadedFiles[tsFile]) {
return;
}
var deps = dependencies[tsFile];
for (var k = 0; k < deps.length; k++) {
addLoadedFile(concatKey, deps[k]);
addFileContent(concatKey, deps[k]);
}
addLoadedFile(concatKey, tsFile);
}
loadFile('ts/core/es5.ts');
loadFile('ts/core/es6.ts');
var items = [];
for (var key in concatItems) {
if (key.indexOf('-compat') > -1) {
continue;
}
if (key === 'lite' || key === 'main' || key === 'core') {
items.unshift(key);
} else {
items.push(key);
}
}
for (var key = 0; key < items.length; key++) {
var concatKey = items[key];
if (!allLoadedFiles[concatKey])
allLoadedFiles[concatKey] = {};
var loadedFiles = allLoadedFiles[concatKey];
var output = [];
var es6Output = [];
var value = concatItems[concatKey];
var src = value.src;
var dest = value.dest;
var dist = false;
if (dest.indexOf('dist/') === 0) {
dist = dest.match(/dist\/(.*?)\.js/)[1];
dest = dest.replace(/dist\/(.*?)\.js/, 'ts/$1.d.ts');
} else if (dest.indexOf('modules/') === 0) {
continue;
} else {
throw new Error("not sure how to handle " + dest);
}
for (var i = 0; i < src.length; i++) {
var file = src[i];
var tsFile = file
.replace(/src\/(.*?).js/, 'ts/$1.ts')
// Is this right 100% of the time?
.replace('perf/operators', 'linq/observable');
if (cache[tsFile] || fs.existsSync(tsFile)) {
if (!cache[tsFile]) {
loadFile(tsFile);
}
if (tsFile.indexOf('/es5') === -1 || tsFile.indexOf('/es6') === -1) {
addFileContent(concatKey, tsFile);
}
} else {
var valid = ['/headers/', '/longstacktraces/', '/internal/', '/autodetachobserver', '/subjects/innersubscription', '/perf/observablebase', 'linq/enumerable/while', '.compat.', 'linq/observable/_', '/linq/observable/fromarrayobservable', '/joins/', '/linq/observable/flatmapbase', '/disposables/scheduleddisposable', '/concurrency/catchscheduler', '/core/observeonobserver', '/testing/mockpromise', '/testing/hotobservable', '/testing/coldobservable'];
var validResult = false;
for (var z = 0; z < valid.length; z++) {
if (tsFile.indexOf(valid[z]) !== -1) {
validResult = true;
break;
}
}
}
}
var writeOut = function(dest, output, es6) {
var outputString = 'declare module Rx {\n' + output.join('') + '\n}\n';
if (concatKey === 'all' || concatKey === 'main' || concatKey === 'lite' || concatKey === 'core') {
outputString += '\ndeclare module "rx" { export = Rx; }\n';
}
if (dist && concatKey !== 'core' && concatKey !== 'main') {
outputString += 'declare module "'+dist+'" { export = Rx; }';
}
outputString = outputString + '\n';
grunt.file.write(dest, outputString);
};
if (concatKey === 'all' || concatKey === 'main' || concatKey === 'lite' || concatKey === 'core') {
output.unshift(cache['ts/core/es5.ts']);
es6Output.unshift(cache['ts/core/es6.ts']);
}
writeOut(dest, output);
writeOut(dest.replace(/.d.ts$/, '.es6.d.ts'), es6Output, true);
}
grunt.file.write('ts/iterable.es6.d.ts', grunt.file.read('ts/core/es6-iterable.d.ts'));
grunt.file.write('ts/es6-promise.es6.d.ts', grunt.file.read('ts/core/es6-promise.d.ts'));
});
grunt.registerTask('concat-min', [
'concat:core',
'concat:core-binding',
'concat:core-testing',
'concat:all',
'concat:all-compat',
'concat:main',
'concat:main-compat',
'concat:aggregates',
'concat:aggregates-lite',
'concat:aggregates-lite-compat',
'concat:async',
'concat:async-compat',
'concat:async-lite',
'concat:async-lite-compat',
'concat:backpressure',
'concat:backpressure-lite',
'concat:backpressure-lite-compat',
'concat:binding',
'concat:coincidence',
'concat:coincidence-lite',
'concat:coincidence-lite-compat',
'concat:experimental',
'concat:experimental-lite',
'concat:experimental-lite-compat',
'concat:joinpatterns',
'concat:joinpatterns-lite',
'concat:joinpatterns-lite-compat',
'concat:lite',
'concat:lite-compat',
'concat:lite-extras',
'concat:lite-extras-compat',
'concat:time',
'concat:time-lite',
'concat:time-lite-compat',
'concat:testing',
'concat:testing-lite',
'concat:testing-lite-compat',
'concat:virtualtime',
'concat:virtualtime-lite',
'concat:virtualtime-lite-compat',
'concat:sorting',
'uglify:core',
'uglify:core-binding',
'uglify:core-testing',
'uglify:all',
'uglify:all-compat',
'uglify:main',
'uglify:main-compat',
'uglify:aggregates',
'uglify:aggregates-lite',
'uglify:aggregates-lite-compat',
'uglify:async',
'uglify:async-compat',
'uglify:async-lite',
'uglify:async-lite-compat',
'uglify:backpressure',
'uglify:backpressure-lite',
'uglify:backpressure-lite-compat',
'uglify:binding',
'uglify:coincidence',
'uglify:coincidence-lite',
'uglify:coincidence-lite-compat',
'uglify:experimental',
'uglify:experimental-lite',
'uglify:experimental-lite-compat',
'uglify:joinpatterns',
'uglify:joinpatterns-lite',
'uglify:joinpatterns-lite-compat',
'uglify:lite',
'uglify:lite-compat',
'uglify:lite-extras',
'uglify:lite-extras-compat',
'uglify:time',
'uglify:time-lite',
'uglify:time-lite-compat',
'uglify:testing',
'uglify:testing-lite',
'uglify:testing-lite-compat',
'uglify:virtualtime',
'uglify:virtualtime-lite',
'uglify:virtualtime-lite-compat',
'uglify:sorting',
'copy:lite',
'copy:lite-compat',
'copy:lite-extras',
'copy:lite-extras-compat',
'copy:core',
'copy:core-binding',
'copy:core-testing'
]);
// Default task
grunt.registerTask('default', [
'concat:core',
'concat:core-binding',
'concat:core-testing',
'concat:all',
'concat:all-compat',
'concat:main',
'concat:main-compat',
'concat:aggregates',
'concat:aggregates-lite',
'concat:aggregates-lite-compat',
'concat:async',
'concat:async-compat',
'concat:async-lite',
'concat:async-lite-compat',
'concat:backpressure',
'concat:backpressure-lite',
'concat:backpressure-lite-compat',
'concat:binding',
'concat:coincidence',
'concat:coincidence-lite',
'concat:coincidence-lite-compat',
'concat:experimental',
'concat:experimental-lite',
'concat:experimental-lite-compat',
'concat:joinpatterns',
'concat:joinpatterns-lite',
'concat:joinpatterns-lite-compat',
'concat:lite',
'concat:lite-compat',
'concat:lite-extras',
'concat:lite-extras-compat',
'concat:time',
'concat:time-lite',
'concat:time-lite-compat',
'concat:testing',
'concat:testing-lite',
'concat:testing-lite-compat',
'concat:virtualtime',
'concat:virtualtime-lite',
'concat:virtualtime-lite-compat',
'concat:sorting',
'uglify:core',
'uglify:core-binding',
'uglify:core-testing',
'uglify:all',
'uglify:all-compat',
'uglify:main',
'uglify:main-compat',
'uglify:aggregates',
'uglify:aggregates-lite',
'uglify:aggregates-lite-compat',
'uglify:async',
'uglify:async-compat',
'uglify:async-lite',
'uglify:async-lite-compat',
'uglify:backpressure',
'uglify:backpressure-lite',
'uglify:backpressure-lite-compat',
'uglify:binding',
'uglify:coincidence',
'uglify:coincidence-lite',
'uglify:coincidence-lite-compat',
'uglify:experimental',
'uglify:experimental-lite',
'uglify:experimental-lite-compat',
'uglify:joinpatterns',
'uglify:joinpatterns-lite',
'uglify:joinpatterns-lite-compat',
'uglify:lite',
'uglify:lite-compat',
'uglify:lite-extras',
'uglify:lite-extras-compat',
'uglify:time',
'uglify:time-lite',
'uglify:time-lite-compat',
'uglify:testing',
'uglify:testing-lite',
'uglify:testing-lite-compat',
'uglify:virtualtime',
'uglify:virtualtime-lite',
'uglify:virtualtime-lite-compat',
'uglify:sorting',
'copy:lite',
'copy:lite-compat',
'copy:lite-extras',
'copy:lite-extras-compat',
'copy:core',
'copy:core-binding',
'copy:core-testing',
'qunit',
'rebuild-ts'
]);
};
================================================
FILE: authors.txt
================================================
Matthew Podwysocki
Bart de Smet
Erik Meijer
================================================
FILE: bower.json
================================================
{
"name": "rxjs",
"main": "dist/rx.all.js",
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"license": "Apache-2.0",
"ignore": [
".sh",
".*",
"*.bat",
"*.md",
"*.txt",
"*.log",
"package.json",
"node_modules",
"doc",
"examples",
"src",
"tests"
]
}
================================================
FILE: code-of-conduct.md
================================================
# Code of Conduct #
[_Adapted from the Rust Code of Conduct_](https://github.com/rust-lang/rust/wiki/Note-development-policy#conduct)
We are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic.
- On any communication medium, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
- Please be kind and courteous. There's no need to be mean or rude.
- Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
- Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
- We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
- Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one the RxJS team immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
- Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
================================================
FILE: component.json
================================================
{
"name": "rx",
"scripts": [
"dist/rx.aggregates.js",
"dist/rx.aggregates.map",
"dist/rx.aggregates.min.js",
"dist/rx.all.compat.js",
"dist/rx.all.compat.map",
"dist/rx.all.compat.min.js",
"dist/rx.all.js",
"dist/rx.all.min.js",
"dist/rx.all.map",
"dist/rx.async.js",
"dist/rx.async.map",
"dist/rx.async.min.js",
"dist/rx.async.compat.js",
"dist/rx.async.compat.map",
"dist/rx.async.compat.min.js",
"dist/rx.backpressure.js",
"dist/rx.backpressure.map",
"dist/rx.backpressure.min.js",
"dist/rx.backpressure.js",
"dist/rx.backpressure.map",
"dist/rx.backpressure.min.js",
"dist/rx.binding.js",
"dist/rx.binding.map",
"dist/rx.binding.min.js",
"dist/rx.coincidence.js",
"dist/rx.coincidence.map",
"dist/rx.coincidence.min.js",
"dist/rx.js",
"dist/rx.map",
"dist/rx.min.js",
"dist/rx.compat.js",
"dist/rx.compat.map",
"dist/rx.compat.min.js",
"dist/rx.experimental.js",
"dist/rx.experimental.map",
"dist/rx.experimental.min.js",
"dist/rx.joinpatterns.js",
"dist/rx.joinpatterns.map",
"dist/rx.joinpatterns.min.js",
"dist/rx.lite.js",
"dist/rx.lite.map",
"dist/rx.lite.min.js",
"dist/rx.lite.compat.js",
"dist/rx.lite.compat.map",
"dist/rx.lite.compat.min.js",
"dist/rx.lite.extras.js",
"dist/rx.lite.extras.map",
"dist/rx.lite.extras.min.js",
"dist/rx.testing.js",
"dist/rx.testing.map",
"dist/rx.testing.min.js",
"dist/rx.time.js",
"dist/rx.time.map",
"dist/rx.time.min.js",
"dist/rx.virtualtime.js",
"dist/rx.virtualtime.map",
"dist/rx.virtualtime.min.js"
]
}
================================================
FILE: contributing.md
================================================
# Contributing to RxJS #
Want to contribute to the Reactive Extensions for JavaScript (RxJS)? There are many ways of helping whether contributing code, documentation, examples, podcasts, videos and presentations.
# Get Involved!
In [the issue tracker](https://github.com/Reactive-Extensions/RxJS/issues), bugs can only be assigned to people who have commit access. Also, we aspire to make as many bugs as possible "owned" by assigning them to a core Rx contributor. Therefore, just because a bug is assigned doesn't mean it's being actively worked on. We (the core contributors) are all busy, and welcome help from the community. If you see a bug you'd like to work on that's assigned but appears to be dormant, communicate with the bug's owner with an @-reply in a comment on the issue page. If you see a bug you'd like to work on that's unassigned, it's fair game: comment to say you'd like to work on it so that we know it's getting attention.
# Pull Requests
To make a pull request, you will need a GitHub account; if you're unclear on this process, see GitHub's documentation on [forking](https://help.github.com/articles/fork-a-repo/) and [pull requests](https://help.github.com/articles/using-pull-requests). Pull requests should be targeted at RxJS's master branch. Before pushing to your Github repo and issuing the pull request, please do two things:
1. Rebase your local changes against the master branch. Resolve any conflicts that arise.
2. Run the full RxJS test suite by running `grunt` in the root of the repository.
Pull requests will be treated as "review requests", and we will give feedback we expect to see corrected on style and substance before pulling. Changes contributed via pull request should focus on a single issue at a time, like any other. We will not look kindly on pull-requests that try to "sneak" unrelated changes in. Note for bug fixes, regression tests should be included, denoted by Issue Number so that we have full traceability.
# What Are We Looking For?
For documentation, we are looking for the following:
- API Documentation that is missing or out of date
- "How Do I?" examples
- Comparison to other libraries
- Comparison to Promises
- Introduction material
- Tutorials
For coding, we have strict standards that must be adhere to when working on RxJS. In order for us to accept pull requests, they must abide by the following:
- [Coding Standard](#coding-standard)
- [Tests](#tests)
- [Documentation](#documentation)
## Coding Standard
For RxJS, we follow the [Google JavaScript Style Guide](http://google.github.io/styleguide/jsguide.html) and adhere to it strictly in areas such as documentation using JSDoc. The only exception to extending native prototypes is to polyfill behavior which may not exist in all browsers yet, for example, many of the [Array#extras](http://blogs.msdn.com/b/ie/archive/2010/12/13/ecmascript-5-part-2-array-extras.aspx) are implemented in compatibility builds. We also strictly follow [our design guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/designguidelines) as well.
### Supporting Multiple Platforms
RxJS runs on a number of platforms and supports many styles of programming. RxJS supports [Universal Module Definition (UMD)](https://github.com/umdjs/umd) which allows the library to work in a number of environments such as [Asynchronous Module Definition (AMD)](https://github.com/amdjs/amdjs-api/wiki/AMD), [CommonJS](http://wiki.commonjs.org/wiki/CommonJS), [Node.js](http://nodejs.org), [RingoJS](http://ringojs.org/), [Narwhal](https://github.com/280north/narwhal), the browser and other environments such as [Windows Script Host (WSH)](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) and embedded devices such as [Tessel](http://tessel.io).
RxJS is committed to using the latest JavaScript standards as they start to arrive, for example, supporting generators, Maps, Sets, and Observable versions of new Array methods. We also are committed to supporting legacy code as well through compatibility builds, even supporting browsers back to IE6, Firefox 3, and older versions of Node.js. Should behavior not exist in those platforms, that behavior must be polyfilled, and made available in `*.compat.js` files only. For example, we have `rx.lite.js` which supports modern browsers greater than or equal to IE9, and `rx.lite.compat.js` for older browsers before IE9 and modern Firefox builds. In special cases such as event handling is different, we must provide a mainstream version of the file as well as a compat file, the latter which is included in the compat file.
### Implementing Custom Operators
We welcome custom operators to RxJS if they make sense in the core RxJS, as opposed to belonging in user land. There are a number of rules that must be adhered to when implementing a custom operator including:
- Prefer composition over implementing a totally new operator from scratch
- If the operator introduces any notion of concurrency, then a scheduler must introduced. Usage of concurrency primitives such as `setTimeout`, `setInterval`, etc are forbidden. This is to ensure easy testability.
- The scheduler must be optional with the appropriate default picked
- `Rx.Scheduler.immediate` for any immediate blocking operations
- `Rx.Scheduler.currentThread` for any immediate blocking operators that require re-entrant behavior such as recursive scheduling.
- `Rx.Scheduler.timeout` for any operator that has a notion of time
To make this concrete, let's implement a custom operator such as an implementation of `_.reject` from [Underscore.js](http://underscorejs.org/) / [Lo-Dash](http://lodash.com/).
```js
/**
* The opposite of _.filter this method returns the elements of a collection that the callback does **not** return truthy for.
* @param {Function} [callback] The function called per iteration.
* @param {Any} [thisArg] The this binding of callback.
* @returns {Observable} An Observable sequence which contains items that the callback does not return truthy for.
*/
Rx.Observable.prototype.reject = function (callback, thisArg) {
callback || (callback = Rx.helpers.identity);
var source = this;
return new Rx.AnonymousObservable(function (observer) {
var i = 0;
return source.subscribe(
function (x) {
var noYield = true;
try {
noYield = callback.call(thisArg, x, i++, source);
} catch (e) {
observer.onError(e);
return;
}
if (!noYield) { observer.onNext(x); }
},
observer.onError.bind(observer),
observer.onCompleted.bind(observer)
);
});
};
```
Of course, we could have implemented this using composition as well, such as using `Rx.Observable.prototype.filter`.
```js
/**
* The opposite of _.filter this method returns the elements of a collection that the callback does **not** return truthy for.
* @param {Function} [callback] The function called per iteration.
* @param {Any} [thisArg] The this binding of callback.
* @returns {Observable} An Observable sequence which contains items that the callback does not return truthy for.
*/
Rx.Observable.prototype.reject = function (callback, thisArg) {
callback || (callback = Rx.helpers.identity);
return this.filter(function (x, i, o) { return !callback.call(thisArg, x, i o); });
};
```
To show an operator that introduces a level of concurrency, let's implement a custom operator such as an implementation of `_.pairs` from [Underscore.js](http://underscorejs.org/) / [Lo-Dash](http://lodash.com/). Note that since this requires recursion to implement properly, we'll use the `Rx.Scheduler.currentThread` scheduler.
```js
var keysFunction = Object.keys || someKeysPolyfill;
/**
* Creates an Observable with an of an object’s key-value pairs.
* @param {Object} obj The object to inspect.
* @returns {Observable} An Observable with an of an object’s key-value pairs.
*/
Rx.Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = Rx.Scheduler.currentThread);
return new Rx.AnonymousObservable(function (observer) {
var keys = keysFunction(object),
i = 0,
len = keys.length;
return scheduler.scheduleRecursive(function (self) {
if (i < len) {
var key = keys[i++], value = obj[key];
observer.onNext([key, value]);
self();
} else {
observer.onCompleted();
}
});
});
};
```
Note that all operators must have the documentation and must be split out into its own file. This allows us to be able to put it in different files, or make it available in custom builds.
## Tests
When a new operator is written for RxJS, in order to accepted, must be accompanied by tests. RxJS currently uses [QUnit](http://qunitjs.com/) as a straight forward way to test our code. These tests are automatically executed by our [Grunt](http://gruntjs.com/) setup to concatenate files, minimize, create source maps, and finally run all the tests in the [tests folder](https://github.com/Reactive-Extensions/RxJS/tree/master/tests). Each file that we produce, for example, `rx.js` has an accompanying test file such as `rx.html`, which includes tests for all operators included in that file.
Each operator under test must be in its own file to cover the following cases:
- Never
- Empty
- Single/Multiple Values
- Error in the sequence
- Never ending sequences
- Early disposal in sequences
If the operator has a callback, then it must cover the following cases:
- Success with all values in the callback
- Success with the context, if any allowed in the operator signature
- If an error is thrown
To get a good feeling on what kind of rigor is required for testing, check out the following examples:
- [`concatMap`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/concatmap.js)
- [`from`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/from.js)
## Documentation
Documentation is also a must, as all external operators and types must be documented and put in the [API Folder](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api). Each operator on an Observable must have its own file in the [Operators Folder](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators).
For operators, they must be linked from the [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md) API document. In addition, each operator must be listed in which file it belongs in the [Libraries Folder](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/libraries).
The standard format of operators must be such as the [`of`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/of.md) operator which includes:
- File Location
- Method signature
- Method description
- List of Arguments
- Return type (if there is one)
- An example
- File Distribution(s)
- NuGet Distribution
- NPM Distribution
- Unit Tests
================================================
FILE: dist/rx.aggregates.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
BinaryDisposable = Rx.BinaryDisposable,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
disposableEmpty = Rx.Disposable.empty,
helpers = Rx.helpers,
defaultComparer = helpers.defaultComparer,
identity = helpers.identity,
defaultSubComparer = helpers.defaultSubComparer,
isFunction = helpers.isFunction,
isPromise = helpers.isPromise,
isArrayLike = helpers.isArrayLike,
isIterable = helpers.isIterable,
inherits = Rx.internals.inherits,
observableFromPromise = Observable.fromPromise,
observableFrom = Observable.from,
bindCallback = Rx.internals.bindCallback,
EmptyError = Rx.EmptyError,
ObservableBase = Rx.ObservableBase,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var ExtremaByObservable = (function (__super__) {
inherits(ExtremaByObservable, __super__);
function ExtremaByObservable(source, k, c) {
this.source = source;
this._k = k;
this._c = c;
__super__.call(this);
}
ExtremaByObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ExtremaByObserver(o, this._k, this._c));
};
return ExtremaByObservable;
}(ObservableBase));
var ExtremaByObserver = (function (__super__) {
inherits(ExtremaByObserver, __super__);
function ExtremaByObserver(o, k, c) {
this._o = o;
this._k = k;
this._c = c;
this._v = null;
this._hv = false;
this._l = [];
__super__.call(this);
}
ExtremaByObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var comparison = 0;
if (!this._hv) {
this._hv = true;
this._v = key;
} else {
comparison = tryCatch(this._c)(key, this._v);
if (comparison === errorObj) { return this._o.onError(comparison.e); }
}
if (comparison > 0) {
this._v = key;
this._l = [];
}
if (comparison >= 0) { this._l.push(x); }
};
ExtremaByObserver.prototype.error = function (e) {
this._o.onError(e);
};
ExtremaByObserver.prototype.completed = function () {
this._o.onNext(this._l);
this._o.onCompleted();
};
return ExtremaByObserver;
}(AbstractObserver));
function firstOnly(x) {
if (x.length === 0) { throw new EmptyError(); }
return x[0];
}
var ReduceObservable = (function(__super__) {
inherits(ReduceObservable, __super__);
function ReduceObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ReduceObservable.prototype.subscribeCore = function(observer) {
return this.source.subscribe(new ReduceObserver(observer,this));
};
return ReduceObservable;
}(ObservableBase));
var ReduceObserver = (function (__super__) {
inherits(ReduceObserver, __super__);
function ReduceObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ReduceObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._i++;
};
ReduceObserver.prototype.error = function (e) {
this._o.onError(e);
};
ReduceObserver.prototype.completed = function () {
this._hv && this._o.onNext(this._a);
!this._hv && this._hs && this._o.onNext(this._s);
!this._hv && !this._hs && this._o.onError(new EmptyError());
this._o.onCompleted();
};
return ReduceObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
* For aggregation behavior with incremental intermediate results, see Observable.scan.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @param {Any} [seed] The initial accumulator value.
* @returns {Observable} An observable sequence containing a single element with the final accumulator value.
*/
observableProto.reduce = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ReduceObservable(this, accumulator, hasSeed, seed);
};
var SomeObservable = (function (__super__) {
inherits(SomeObservable, __super__);
function SomeObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SomeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SomeObserver(o, this._fn, this.source));
};
return SomeObservable;
}(ObservableBase));
var SomeObserver = (function (__super__) {
inherits(SomeObserver, __super__);
function SomeObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
SomeObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (Boolean(result)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
SomeObserver.prototype.error = function (e) { this._o.onError(e); };
SomeObserver.prototype.completed = function () {
this._o.onNext(false);
this._o.onCompleted();
};
return SomeObserver;
}(AbstractObserver));
/**
* Determines whether any element of an observable sequence satisfies a condition if present, else if any items are in the sequence.
* @param {Function} [predicate] A function to test each element for a condition.
* @returns {Observable} An observable sequence containing a single element determining whether any elements in the source sequence pass the test in the specified predicate if given, else if any items are in the sequence.
*/
observableProto.some = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SomeObservable(this, fn);
};
var IsEmptyObservable = (function (__super__) {
inherits(IsEmptyObservable, __super__);
function IsEmptyObservable(source) {
this.source = source;
__super__.call(this);
}
IsEmptyObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new IsEmptyObserver(o));
};
return IsEmptyObservable;
}(ObservableBase));
var IsEmptyObserver = (function(__super__) {
inherits(IsEmptyObserver, __super__);
function IsEmptyObserver(o) {
this._o = o;
__super__.call(this);
}
IsEmptyObserver.prototype.next = function () {
this._o.onNext(false);
this._o.onCompleted();
};
IsEmptyObserver.prototype.error = function (e) { this._o.onError(e); };
IsEmptyObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return IsEmptyObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence is empty.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence is empty.
*/
observableProto.isEmpty = function () {
return new IsEmptyObservable(this);
};
var EveryObservable = (function (__super__) {
inherits(EveryObservable, __super__);
function EveryObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
EveryObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new EveryObserver(o, this._fn, this.source));
};
return EveryObservable;
}(ObservableBase));
var EveryObserver = (function (__super__) {
inherits(EveryObserver, __super__);
function EveryObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
EveryObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (!Boolean(result)) {
this._o.onNext(false);
this._o.onCompleted();
}
};
EveryObserver.prototype.error = function (e) { this._o.onError(e); };
EveryObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return EveryObserver;
}(AbstractObserver));
/**
* Determines whether all elements of an observable sequence satisfy a condition.
* @param {Function} [predicate] A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.
*/
observableProto.every = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new EveryObservable(this, fn);
};
var IncludesObservable = (function (__super__) {
inherits(IncludesObservable, __super__);
function IncludesObservable(source, elem, idx) {
var n = +idx || 0;
Math.abs(n) === Infinity && (n = 0);
this.source = source;
this._elem = elem;
this._n = n;
__super__.call(this);
}
IncludesObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(false);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IncludesObserver(o, this._elem, this._n));
};
return IncludesObservable;
}(ObservableBase));
var IncludesObserver = (function (__super__) {
inherits(IncludesObserver, __super__);
function IncludesObserver(o, elem, n) {
this._o = o;
this._elem = elem;
this._n = n;
this._i = 0;
__super__.call(this);
}
function comparer(a, b) {
return (a === 0 && b === 0) || (a === b || (isNaN(a) && isNaN(b)));
}
IncludesObserver.prototype.next = function (x) {
if (this._i++ >= this._n && comparer(x, this._elem)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
IncludesObserver.prototype.error = function (e) { this._o.onError(e); };
IncludesObserver.prototype.completed = function () { this._o.onNext(false); this._o.onCompleted(); };
return IncludesObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence includes a specified element with an optional equality comparer.
* @param searchElement The value to locate in the source sequence.
* @param {Number} [fromIndex] An equality comparer to compare elements.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence includes an element that has the specified value from the given index.
*/
observableProto.includes = function (searchElement, fromIndex) {
return new IncludesObservable(this, searchElement, fromIndex);
};
var CountObservable = (function (__super__) {
inherits(CountObservable, __super__);
function CountObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
CountObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new CountObserver(o, this._fn, this.source));
};
return CountObservable;
}(ObservableBase));
var CountObserver = (function (__super__) {
inherits(CountObserver, __super__);
function CountObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
CountObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
Boolean(result) && (this._c++);
} else {
this._c++;
}
};
CountObserver.prototype.error = function (e) { this._o.onError(e); };
CountObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return CountObserver;
}(AbstractObserver));
/**
* Returns an observable sequence containing a value that represents how many elements in the specified observable sequence satisfy a condition if provided, else the count of items.
* @example
* res = source.count();
* res = source.count(function (x) { return x > 3; });
* @param {Function} [predicate]A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function if provided, else the count of items in the sequence.
*/
observableProto.count = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new CountObservable(this, fn);
};
var IndexOfObservable = (function (__super__) {
inherits(IndexOfObservable, __super__);
function IndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
IndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IndexOfObserver(o, this._e, this._n));
};
return IndexOfObservable;
}(ObservableBase));
var IndexOfObserver = (function (__super__) {
inherits(IndexOfObserver, __super__);
function IndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._i = 0;
__super__.call(this);
}
IndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._o.onNext(this._i);
this._o.onCompleted();
}
this._i++;
};
IndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
IndexOfObserver.prototype.completed = function () { this._o.onNext(-1); this._o.onCompleted(); };
return IndexOfObserver;
}(AbstractObserver));
/**
* Returns the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.indexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new IndexOfObservable(this, searchElement, n);
};
var SumObservable = (function (__super__) {
inherits(SumObservable, __super__);
function SumObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SumObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SumObserver(o, this._fn, this.source));
};
return SumObservable;
}(ObservableBase));
var SumObserver = (function (__super__) {
inherits(SumObserver, __super__);
function SumObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
SumObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
this._c += result;
} else {
this._c += x;
}
};
SumObserver.prototype.error = function (e) { this._o.onError(e); };
SumObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return SumObserver;
}(AbstractObserver));
/**
* Computes the sum of a sequence of values that are obtained by invoking an optional transform function on each element of the input sequence, else if not specified computes the sum on each item in the sequence.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the sum of the values in the source sequence.
*/
observableProto.sum = function (keySelector, thisArg) {
var fn = bindCallback(keySelector, thisArg, 3);
return new SumObservable(this, fn);
};
/**
* Returns the elements in an observable sequence with the minimum key value according to the specified comparer.
* @example
* var res = source.minBy(function (x) { return x.value; });
* var res = source.minBy(function (x) { return x.value; }, function (x, y) { return x - y; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a minimum key value.
*/
observableProto.minBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, function (x, y) { return comparer(x, y) * -1; });
};
/**
* Returns the minimum element in an observable sequence according to the optional comparer else a default greater than less than check.
* @example
* var res = source.min();
* var res = source.min(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the minimum element in the source sequence.
*/
observableProto.min = function (comparer) {
return this.minBy(identity, comparer).map(firstOnly);
};
/**
* Returns the elements in an observable sequence with the maximum key value according to the specified comparer.
* @example
* var res = source.maxBy(function (x) { return x.value; });
* var res = source.maxBy(function (x) { return x.value; }, function (x, y) { return x - y;; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a maximum key value.
*/
observableProto.maxBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, comparer);
};
/**
* Returns the maximum value in an observable sequence according to the specified comparer.
* @example
* var res = source.max();
* var res = source.max(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the maximum element in the source sequence.
*/
observableProto.max = function (comparer) {
return this.maxBy(identity, comparer).map(firstOnly);
};
var AverageObservable = (function (__super__) {
inherits(AverageObservable, __super__);
function AverageObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
AverageObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new AverageObserver(o, this._fn, this.source));
};
return AverageObservable;
}(ObservableBase));
var AverageObserver = (function(__super__) {
inherits(AverageObserver, __super__);
function AverageObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._c = 0;
this._t = 0;
__super__.call(this);
}
AverageObserver.prototype.next = function (x) {
if(this._fn) {
var r = tryCatch(this._fn)(x, this._c++, this._s);
if (r === errorObj) { return this._o.onError(r.e); }
this._t += r;
} else {
this._c++;
this._t += x;
}
};
AverageObserver.prototype.error = function (e) { this._o.onError(e); };
AverageObserver.prototype.completed = function () {
if (this._c === 0) { return this._o.onError(new EmptyError()); }
this._o.onNext(this._t / this._c);
this._o.onCompleted();
};
return AverageObserver;
}(AbstractObserver));
/**
* Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the average of the sequence of values.
*/
observableProto.average = function (keySelector, thisArg) {
var source = this, fn;
if (isFunction(keySelector)) {
fn = bindCallback(keySelector, thisArg, 3);
}
return new AverageObservable(source, fn);
};
/**
* Determines whether two sequences are equal by comparing the elements pairwise using a specified equality comparer.
*
* @example
* var res = res = source.sequenceEqual([1,2,3]);
* var res = res = source.sequenceEqual([{ value: 42 }], function (x, y) { return x.value === y.value; });
* 3 - res = source.sequenceEqual(Rx.Observable.returnValue(42));
* 4 - res = source.sequenceEqual(Rx.Observable.returnValue({ value: 42 }), function (x, y) { return x.value === y.value; });
* @param {Observable} second Second observable sequence or array to compare.
* @param {Function} [comparer] Comparer used to compare elements of both sequences.
* @returns {Observable} An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.
*/
observableProto.sequenceEqual = function (second, comparer) {
var first = this;
comparer || (comparer = defaultComparer);
return new AnonymousObservable(function (o) {
var donel = false, doner = false, ql = [], qr = [];
var subscription1 = first.subscribe(function (x) {
if (qr.length > 0) {
var v = qr.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (doner) {
o.onNext(false);
o.onCompleted();
} else {
ql.push(x);
}
}, function(e) { o.onError(e); }, function () {
donel = true;
if (ql.length === 0) {
if (qr.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (doner) {
o.onNext(true);
o.onCompleted();
}
}
});
(isArrayLike(second) || isIterable(second)) && (second = observableFrom(second));
isPromise(second) && (second = observableFromPromise(second));
var subscription2 = second.subscribe(function (x) {
if (ql.length > 0) {
var v = ql.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (donel) {
o.onNext(false);
o.onCompleted();
} else {
qr.push(x);
}
}, function(e) { o.onError(e); }, function () {
doner = true;
if (qr.length === 0) {
if (ql.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (donel) {
o.onNext(true);
o.onCompleted();
}
}
});
return new BinaryDisposable(subscription1, subscription2);
}, first);
};
var ElementAtObservable = (function (__super__) {
inherits(ElementAtObservable, __super__);
function ElementAtObservable(source, i, d) {
this.source = source;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ElementAtObserver(o, this._i, this._d));
};
return ElementAtObservable;
}(ObservableBase));
var ElementAtObserver = (function (__super__) {
inherits(ElementAtObserver, __super__);
function ElementAtObserver(o, i, d) {
this._o = o;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObserver.prototype.next = function (x) {
if (this._i-- === 0) {
this._o.onNext(x);
this._o.onCompleted();
}
};
ElementAtObserver.prototype.error = function (e) { this._o.onError(e); };
ElementAtObserver.prototype.completed = function () {
if (this._d === undefined) {
this._o.onError(new ArgumentOutOfRangeError());
} else {
this._o.onNext(this._d);
this._o.onCompleted();
}
};
return ElementAtObserver;
}(AbstractObserver));
/**
* Returns the element at a specified index in a sequence or default value if not found.
* @param {Number} index The zero-based index of the element to retrieve.
* @param {Any} [defaultValue] The default value to use if elementAt does not find a value.
* @returns {Observable} An observable sequence that produces the element at the specified position in the source sequence.
*/
observableProto.elementAt = function (index, defaultValue) {
if (index < 0) { throw new ArgumentOutOfRangeError(); }
return new ElementAtObservable(this, index, defaultValue);
};
var SingleObserver = (function(__super__) {
inherits(SingleObserver, __super__);
function SingleObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
SingleObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
if (this._hv) {
return this._o.onError(new Error('Sequence contains more than one matching element'));
}
this._hv = true;
this._v = x;
}
};
SingleObserver.prototype.error = function (e) { this._o.onError(e); };
SingleObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return SingleObserver;
}(AbstractObserver));
/**
* Returns the only element of an observable sequence that satisfies the condition in the optional predicate, and reports an exception if there is not exactly one element in the observable sequence.
* @returns {Observable} Sequence containing the single element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.single = function (predicate, thisArg) {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new AnonymousObservable(function (o) {
return source.subscribe(new SingleObserver(o, obj, source));
}, source);
};
var FirstObservable = (function (__super__) {
inherits(FirstObservable, __super__);
function FirstObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
FirstObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FirstObserver(o, this._obj, this.source));
};
return FirstObservable;
}(ObservableBase));
var FirstObserver = (function(__super__) {
inherits(FirstObserver, __super__);
function FirstObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
__super__.call(this);
}
FirstObserver.prototype.next = function (x) {
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
if (Boolean(res)) {
this._o.onNext(x);
this._o.onCompleted();
}
} else if (!this._obj.predicate) {
this._o.onNext(x);
this._o.onCompleted();
}
};
FirstObserver.prototype.error = function (e) { this._o.onError(e); };
FirstObserver.prototype.completed = function () {
if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return FirstObserver;
}(AbstractObserver));
/**
* Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence.
* @returns {Observable} Sequence containing the first element in the observable sequence that satisfies the condition in the predicate if provided, else the first item in the sequence.
*/
observableProto.first = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new FirstObservable(this, obj);
};
var LastObservable = (function (__super__) {
inherits(LastObservable, __super__);
function LastObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
LastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new LastObserver(o, this._obj, this.source));
};
return LastObservable;
}(ObservableBase));
var LastObserver = (function(__super__) {
inherits(LastObserver, __super__);
function LastObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
LastObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
this._hv = true;
this._v = x;
}
};
LastObserver.prototype.error = function (e) { this._o.onError(e); };
LastObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return LastObserver;
}(AbstractObserver));
/**
* Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element.
* @returns {Observable} Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.last = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new LastObservable(this, obj);
};
var FindValueObserver = (function(__super__) {
inherits(FindValueObserver, __super__);
function FindValueObserver(observer, source, callback, yieldIndex) {
this._o = observer;
this._s = source;
this._cb = callback;
this._y = yieldIndex;
this._i = 0;
__super__.call(this);
}
FindValueObserver.prototype.next = function (x) {
var shouldRun = tryCatch(this._cb)(x, this._i, this._s);
if (shouldRun === errorObj) { return this._o.onError(shouldRun.e); }
if (shouldRun) {
this._o.onNext(this._y ? this._i : x);
this._o.onCompleted();
} else {
this._i++;
}
};
FindValueObserver.prototype.error = function (e) {
this._o.onError(e);
};
FindValueObserver.prototype.completed = function () {
this._y && this._o.onNext(-1);
this._o.onCompleted();
};
return FindValueObserver;
}(AbstractObserver));
function findValue (source, predicate, thisArg, yieldIndex) {
var callback = bindCallback(predicate, thisArg, 3);
return new AnonymousObservable(function (o) {
return source.subscribe(new FindValueObserver(o, source, callback, yieldIndex));
}, source);
}
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the first element that matches the conditions defined by the specified predicate, if found; otherwise, undefined.
*/
observableProto.find = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, false);
};
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns
* an Observable sequence with the zero-based index of the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
*/
observableProto.findIndex = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, true);
};
var ToSetObservable = (function (__super__) {
inherits(ToSetObservable, __super__);
function ToSetObservable(source) {
this.source = source;
__super__.call(this);
}
ToSetObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToSetObserver(o));
};
return ToSetObservable;
}(ObservableBase));
var ToSetObserver = (function (__super__) {
inherits(ToSetObserver, __super__);
function ToSetObserver(o) {
this._o = o;
this._s = new root.Set();
__super__.call(this);
}
ToSetObserver.prototype.next = function (x) {
this._s.add(x);
};
ToSetObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToSetObserver.prototype.completed = function () {
this._o.onNext(this._s);
this._o.onCompleted();
};
return ToSetObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Set if it exists.
* @returns {Observable} An observable sequence with a single value of a Set containing the values from the observable sequence.
*/
observableProto.toSet = function () {
if (typeof root.Set === 'undefined') { throw new TypeError(); }
return new ToSetObservable(this);
};
var ToMapObservable = (function (__super__) {
inherits(ToMapObservable, __super__);
function ToMapObservable(source, k, e) {
this.source = source;
this._k = k;
this._e = e;
__super__.call(this);
}
ToMapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToMapObserver(o, this._k, this._e));
};
return ToMapObservable;
}(ObservableBase));
var ToMapObserver = (function (__super__) {
inherits(ToMapObserver, __super__);
function ToMapObserver(o, k, e) {
this._o = o;
this._k = k;
this._e = e;
this._m = new root.Map();
__super__.call(this);
}
ToMapObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var elem = x;
if (this._e) {
elem = tryCatch(this._e)(x);
if (elem === errorObj) { return this._o.onError(elem.e); }
}
this._m.set(key, elem);
};
ToMapObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToMapObserver.prototype.completed = function () {
this._o.onNext(this._m);
this._o.onCompleted();
};
return ToMapObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Map if it exists.
* @param {Function} keySelector A function which produces the key for the Map.
* @param {Function} [elementSelector] An optional function which produces the element for the Map. If not present, defaults to the value from the observable sequence.
* @returns {Observable} An observable sequence with a single value of a Map containing the values from the observable sequence.
*/
observableProto.toMap = function (keySelector, elementSelector) {
if (typeof root.Map === 'undefined') { throw new TypeError(); }
return new ToMapObservable(this, keySelector, elementSelector);
};
var SliceObservable = (function (__super__) {
inherits(SliceObservable, __super__);
function SliceObservable(source, b, e) {
this.source = source;
this._b = b;
this._e = e;
__super__.call(this);
}
SliceObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SliceObserver(o, this._b, this._e));
};
return SliceObservable;
}(ObservableBase));
var SliceObserver = (function (__super__) {
inherits(SliceObserver, __super__);
function SliceObserver(o, b, e) {
this._o = o;
this._b = b;
this._e = e;
this._i = 0;
__super__.call(this);
}
SliceObserver.prototype.next = function (x) {
if (this._i >= this._b) {
if (this._e === this._i) {
this._o.onCompleted();
} else {
this._o.onNext(x);
}
}
this._i++;
};
SliceObserver.prototype.error = function (e) { this._o.onError(e); };
SliceObserver.prototype.completed = function () { this._o.onCompleted(); };
return SliceObserver;
}(AbstractObserver));
/*
* The slice() method returns a shallow copy of a portion of an Observable into a new Observable object.
* Unlike the array version, this does not support negative numbers for being or end.
* @param {Number} [begin] Zero-based index at which to begin extraction. If omitted, this will default to zero.
* @param {Number} [end] Zero-based index at which to end extraction. slice extracts up to but not including end.
* If omitted, this will emit the rest of the Observable object.
* @returns {Observable} A shallow copy of a portion of an Observable into a new Observable object.
*/
observableProto.slice = function (begin, end) {
var start = begin || 0;
if (start < 0) { throw new Rx.ArgumentOutOfRangeError(); }
if (typeof end === 'number' && end < start) {
throw new Rx.ArgumentOutOfRangeError();
}
return new SliceObservable(this, start, end);
};
var LastIndexOfObservable = (function (__super__) {
inherits(LastIndexOfObservable, __super__);
function LastIndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
LastIndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new LastIndexOfObserver(o, this._e, this._n));
};
return LastIndexOfObservable;
}(ObservableBase));
var LastIndexOfObserver = (function (__super__) {
inherits(LastIndexOfObserver, __super__);
function LastIndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._v = 0;
this._hv = false;
this._i = 0;
__super__.call(this);
}
LastIndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._hv = true;
this._v = this._i;
}
this._i++;
};
LastIndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
LastIndexOfObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
} else {
this._o.onNext(-1);
}
this._o.onCompleted();
};
return LastIndexOfObserver;
}(AbstractObserver));
/**
* Returns the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.lastIndexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new LastIndexOfObservable(this, searchElement, n);
};
return Rx;
}));
================================================
FILE: dist/rx.all.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
// Utilities
var toString = Object.prototype.toString;
var arrayClass = '[object Array]',
funcClass = '[object Function]',
stringClass = '[object String]';
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k++;
}
};
}
var boxedString = Object('a'),
splitString = boxedString[0] !== 'a' || !(0 in boxedString);
if (!Array.prototype.every) {
Array.prototype.every = function every(fun /*, thisp */) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self && !fun.call(thisp, self[i], i, object)) {
return false;
}
}
return true;
};
}
if (!Array.prototype.map) {
Array.prototype.map = function map(fun /*, thisp*/) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
result = new Array(length),
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self) {
result[i] = fun.call(thisp, self[i], i, object);
}
}
return result;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function (predicate) {
var results = [], item, t = new Object(this);
for (var i = 0, len = t.length >>> 0; i < len; i++) {
item = t[i];
if (i in t && predicate.call(arguments[1], item, i, t)) {
results.push(item);
}
}
return results;
};
}
if (!Array.isArray) {
Array.isArray = function (arg) {
return toString.call(arg) === arrayClass;
};
}
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(searchElement) {
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== Infinity && n !== -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
// Fix for Tessel
if (!Object.prototype.propertyIsEnumerable) {
Object.prototype.propertyIsEnumerable = function (key) {
for (var k in this) { if (k === key) { return true; } }
return false;
};
}
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
if (typeof Object.create !== 'function') {
// Production steps of ECMA-262, Edition 5, 15.2.3.5
// Reference: http://es5.github.io/#x15.2.3.5
Object.create = (function() {
function Temp() {}
var hasOwn = Object.prototype.hasOwnProperty;
return function (O) {
if (typeof O !== 'object') {
throw new TypeError('Object prototype may only be an Object or null');
}
Temp.prototype = O;
var obj = new Temp();
Temp.prototype = null;
if (arguments.length > 1) {
// Object.defineProperties does ToObject on its first argument.
var Properties = Object(arguments[1]);
for (var prop in Properties) {
if (hasOwn.call(Properties, prop)) {
obj[prop] = Properties[prop];
}
}
}
// 5. Return obj
return obj;
};
})();
}
root.Element && root.Element.prototype.attachEvent && !root.Element.prototype.addEventListener && (function () {
function addMethod(name, fn) {
Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = fn;
}
addMethod('addEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
target.attachEvent('on' + type, typeListeners.event = function (e) {
e || (e = root.event);
var documentElement = target.document &&
target.document.documentElement ||
target.documentElement ||
{ scrollLeft: 0, scrollTop: 0 };
e.currentTarget = target;
e.pageX = e.clientX + documentElement.scrollLeft;
e.pageY = e.clientY + documentElement.scrollTop;
e.preventDefault = function () {
e.bubbledKeyCode = e.keyCode;
if (e.ctrlKey) {
try {
e.keyCode = 0;
} catch (e) { }
}
e.defaultPrevented = true;
e.returnValue = false;
e.modified = true;
e.returnValue = false;
};
e.stopImmediatePropagation = function () {
immediatePropagation = false;
e.cancelBubble = true;
};
e.stopPropagation = function () {
e.cancelBubble = true;
};
e.relatedTarget = e.fromElement || null;
e.target = e.srcElement || target;
e.timeStamp = +new Date();
// Normalize key events
switch(e.type) {
case 'keypress':
var c = ('charCode' in e ? e.charCode : e.keyCode);
if (c === 10) {
c = 0;
e.keyCode = 13;
} else if (c === 13 || c === 27) {
c = 0;
} else if (c === 3) {
c = 99;
}
e.charCode = c;
e.keyChar = e.charCode ? String.fromCharCode(e.charCode) : '';
break;
}
var copiedEvent = {};
for (var prop in e) {
copiedEvent[prop] = e[prop];
}
for (var i = 0, typeListenersCache = [].concat(typeListeners), typeListenerCache, immediatePropagation = true; immediatePropagation && (typeListenerCache = typeListenersCache[i]); ++i) {
for (var ii = 0, typeListener; typeListener = typeListeners[ii]; ++ii) {
if (typeListener === typeListenerCache) { typeListener.call(target, copiedEvent); break; }
}
}
});
typeListeners.push(listener);
});
addMethod('removeEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
for (var i = typeListeners.length - 1, typeListener; typeListener = typeListeners[i]; --i) {
if (typeListener === listener) { typeListeners.splice(i, 1); break; }
}
!typeListeners.length &&
typeListeners.event &&
target.detachEvent('on' + type, typeListeners.event);
});
addMethod('dispatchEvent', function (e) {
var target = this;
var type = e.type;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
try {
return target.fireEvent('on' + type, e);
} catch (err) {
return typeListeners.event && typeListeners.event(e);
}
});
function ready() {
if (ready.interval && document.body) {
ready.interval = clearInterval(ready.interval);
document.dispatchEvent(new CustomEvent('DOMContentLoaded'));
}
}
ready.interval = setInterval(ready, 1);
root.addEventListener('load', ready);
}());
(!root.CustomEvent || typeof root.CustomEvent === 'object') && (function() {
function CustomEvent (type, params) {
var event;
params = params || { bubbles: false, cancelable: false, detail: undefined };
try {
if (document.createEvent) {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
} else if (document.createEventObject) {
event = document.createEventObject();
}
} catch (error) {
event = document.createEvent('Event');
event.initEvent(type, params.bubbles, params.cancelable);
event.detail = params.detail;
}
return event;
}
root.CustomEvent && (CustomEvent.prototype = root.CustomEvent.prototype);
root.CustomEvent = CustomEvent;
}());
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
schedulerProto.catchError = schedulerProto['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
var CatchScheduler = (function (__super__) {
inherits(CatchScheduler, __super__);
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
__super__.call(this);
}
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () { return this._scheduler.now(); };
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) { thrower(res.e); }
return disposableEmpty;
}
return disposableFixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this, failed = false, d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) { return null; }
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) { thrower(res.e); }
d.dispose();
return null;
}
return res;
}));
return d;
};
return CatchScheduler;
}(Scheduler));
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var self = this;
return new AnonymousObserver(
function (x) { self.onNext(x); },
function (err) { self.onError(err); },
function () { self.onCompleted(); });
};
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var cb = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return cb(notificationCreateOnNext(x));
}, function (e) {
return cb(notificationCreateOnError(e));
}, function () {
return cb(notificationCreateOnCompleted());
});
};
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.prototype.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
Observer.prototype.makeSafe = function(disposable) {
return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var FromPromiseObservable = (function(__super__) {
inherits(FromPromiseObservable, __super__);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
__super__.call(this);
}
function scheduleNext(s, state) {
var o = state[0], data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0], err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function(o) {
var sad = new SingleAssignmentDisposable(), self = this, p = this._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p
.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
return FromPromiseObservable;
}(ObservableBase));
/**
* Converts a Promise to an Observable sequence
* @param {Promise} An ES6 Compliant promise.
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
var observableFromPromise = Observable.fromPromise = function (promise, scheduler) {
scheduler || (scheduler = defaultScheduler);
return new FromPromiseObservable(promise, scheduler);
};
/*
* Converts an existing observable sequence to an ES6 Compatible Promise
* @example
* var promise = Rx.Observable.return(42).toPromise(RSVP.Promise);
*
* // With config
* Rx.config.Promise = RSVP.Promise;
* var promise = Rx.Observable.return(42).toPromise();
* @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise.
* @returns {Promise} An ES6 compatible promise with the last value from the observable sequence.
*/
observableProto.toPromise = function (promiseCtor) {
promiseCtor || (promiseCtor = Rx.config.Promise);
if (!promiseCtor) { throw new NotSupportedError('Promise type not provided nor in Rx.config.Promise'); }
var source = this;
return new promiseCtor(function (resolve, reject) {
// No cancellation can be done
var value;
source.subscribe(function (v) {
value = v;
}, reject, function () {
resolve(value);
});
});
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
/**
* Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.concatMapObserver = observableProto.selectConcatObserver = function(onNext, onError, onCompleted, thisArg) {
var source = this,
onNextFunc = bindCallback(onNext, thisArg, 2),
onErrorFunc = bindCallback(onError, thisArg, 1),
onCompletedFunc = bindCallback(onCompleted, thisArg, 0);
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNextFunc(x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onErrorFunc(err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompletedFunc();
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, this).concatAll();
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
*
* @example
* var res = observable.groupBy(function (x) { return x.id; });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} [elementSelector] A function to map each source element to an element in an observable group.
* @returns {Observable} A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
*/
observableProto.groupBy = function (keySelector, elementSelector) {
return this.groupByUntil(keySelector, elementSelector, observableNever);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function.
* A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
* key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
*
* @example
* var res = observable.groupByUntil(function (x) { return x.id; }, null, function () { return Rx.Observable.never(); });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} durationSelector A function to signal the expiration of a group.
* @returns {Observable}
* A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
* If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
*
*/
observableProto.groupByUntil = function (keySelector, elementSelector, durationSelector) {
var source = this;
return new AnonymousObservable(function (o) {
var map = new Map(),
groupDisposable = new CompositeDisposable(),
refCountDisposable = new RefCountDisposable(groupDisposable),
handleError = function (e) { return function (item) { item.onError(e); }; };
groupDisposable.add(
source.subscribe(function (x) {
var key = tryCatch(keySelector)(x);
if (key === errorObj) {
map.forEach(handleError(key.e));
return o.onError(key.e);
}
var fireNewMapEntry = false, writer = map.get(key);
if (writer === undefined) {
writer = new Subject();
map.set(key, writer);
fireNewMapEntry = true;
}
if (fireNewMapEntry) {
var group = new GroupedObservable(key, writer, refCountDisposable),
durationGroup = new GroupedObservable(key, writer);
var duration = tryCatch(durationSelector)(durationGroup);
if (duration === errorObj) {
map.forEach(handleError(duration.e));
return o.onError(duration.e);
}
o.onNext(group);
var md = new SingleAssignmentDisposable();
groupDisposable.add(md);
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
map.forEach(handleError(e));
o.onError(e);
},
function () {
if (map['delete'](key)) { writer.onCompleted(); }
groupDisposable.remove(md);
}));
}
var element = x;
if (isFunction(elementSelector)) {
element = tryCatch(elementSelector)(x);
if (element === errorObj) {
map.forEach(handleError(element.e));
return o.onError(element.e);
}
}
writer.onNext(element);
}, function (e) {
map.forEach(handleError(e));
o.onError(e);
}, function () {
map.forEach(function (item) { item.onCompleted(); });
o.onCompleted();
}));
return refCountDisposable;
}, source);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
/**
* Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.flatMapObserver = observableProto.selectManyObserver = function (onNext, onError, onCompleted, thisArg) {
var source = this;
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNext.call(thisArg, x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onError.call(thisArg, err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompleted.call(thisArg);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, source).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
work = state.q.shift();
} else {
state.isAcquired = false;
return;
}
var m1 = new SingleAssignmentDisposable();
state.d.add(m1);
m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
recurse([state, self]);
}
ExpandObservable.prototype._ensureActive = function (state) {
var isOwner = false;
if (state.q.length > 0) {
isOwner = !state.isAcquired;
state.isAcquired = true;
}
isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
};
ExpandObservable.prototype.subscribeCore = function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
state = {
q: [],
m: m,
d: d,
activeCount: 0,
isAcquired: false,
o: o
};
state.q.push(this.source);
state.activeCount++;
this._ensureActive(state);
return d;
};
return ExpandObservable;
}(ObservableBase));
var ExpandObserver = (function(__super__) {
inherits(ExpandObserver, __super__);
function ExpandObserver(state, parent, m1) {
this._s = state;
this._p = parent;
this._m1 = m1;
__super__.call(this);
}
ExpandObserver.prototype.next = function (x) {
this._s.o.onNext(x);
var result = tryCatch(this._p._fn)(x);
if (result === errorObj) { return this._s.o.onError(result.e); }
this._s.q.push(result);
this._s.activeCount++;
this._p._ensureActive(this._s);
};
ExpandObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ExpandObserver.prototype.completed = function () {
this._s.d.remove(this._m1);
this._s.activeCount--;
this._s.activeCount === 0 && this._s.o.onCompleted();
};
return ExpandObserver;
}(AbstractObserver));
/**
* Expands an observable sequence by recursively invoking selector.
*
* @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
* @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
* @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
*/
observableProto.expand = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new ExpandObservable(this, selector, scheduler);
};
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ForkJoinObservable = (function (__super__) {
inherits(ForkJoinObservable, __super__);
function ForkJoinObservable(sources, cb) {
this._sources = sources;
this._cb = cb;
__super__.call(this);
}
ForkJoinObservable.prototype.subscribeCore = function (o) {
if (this._sources.length === 0) {
o.onCompleted();
return disposableEmpty;
}
var count = this._sources.length;
var state = {
finished: false,
hasResults: new Array(count),
hasCompleted: new Array(count),
results: new Array(count)
};
var subscriptions = new CompositeDisposable();
for (var i = 0, len = this._sources.length; i < len; i++) {
var source = this._sources[i];
isPromise(source) && (source = observableFromPromise(source));
subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
}
return subscriptions;
};
return ForkJoinObservable;
}(ObservableBase));
var ForkJoinObserver = (function(__super__) {
inherits(ForkJoinObserver, __super__);
function ForkJoinObserver(o, s, i, cb, subs) {
this._o = o;
this._s = s;
this._i = i;
this._cb = cb;
this._subs = subs;
__super__.call(this);
}
ForkJoinObserver.prototype.next = function (x) {
if (!this._s.finished) {
this._s.hasResults[this._i] = true;
this._s.results[this._i] = x;
}
};
ForkJoinObserver.prototype.error = function (e) {
this._s.finished = true;
this._o.onError(e);
this._subs.dispose();
};
ForkJoinObserver.prototype.completed = function () {
if (!this._s.finished) {
if (!this._s.hasResults[this._i]) {
return this._o.onCompleted();
}
this._s.hasCompleted[this._i] = true;
for (var i = 0; i < this._s.results.length; i++) {
if (!this._s.hasCompleted[i]) { return; }
}
this._s.finished = true;
var res = tryCatch(this._cb).apply(null, this._s.results);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
this._o.onCompleted();
}
};
return ForkJoinObserver;
}(AbstractObserver));
/**
* Runs all observable sequences in parallel and collect their last elements.
*
* @example
* 1 - res = Rx.Observable.forkJoin([obs1, obs2]);
* 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...);
* @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences.
*/
Observable.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new ForkJoinObservable(args, resultSelector);
};
/**
* Runs two observable sequences in parallel and combines their last elemenets.
* @param {Observable} second Second observable sequence.
* @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences.
* @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences.
*/
observableProto.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return Observable.forkJoin.apply(null, args);
};
/**
* Comonadic bind operator.
* @param {Function} selector A transform function to apply to each element.
* @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
* @returns {Observable} An observable sequence which results from the comonadic bind operation.
*/
observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
var source = this;
return observableDefer(function () {
var chain;
return source
.map(function (x) {
var curr = new ChainObservable(x);
chain && chain.onNext(x);
chain = curr;
return curr;
})
.tap(
noop,
function (e) { chain && chain.onError(e); },
function () { chain && chain.onCompleted(); }
)
.observeOn(scheduler)
.map(selector);
}, source);
};
var ChainObservable = (function (__super__) {
inherits(ChainObservable, __super__);
function ChainObservable(head) {
__super__.call(this);
this.head = head;
this.tail = new AsyncSubject();
}
addProperties(ChainObservable.prototype, Observer, {
_subscribe: function (o) {
var g = new CompositeDisposable();
g.add(currentThreadScheduler.schedule(this, function (_, self) {
o.onNext(self.head);
g.add(self.tail.mergeAll().subscribe(o));
}));
return g;
},
onCompleted: function () {
this.onNext(Observable.empty());
},
onError: function (e) {
this.onNext(Observable['throw'](e));
},
onNext: function (v) {
this.tail.onNext(v);
this.tail.onCompleted();
}
});
return ChainObservable;
}(Observable));
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this.patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this.patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
function Plan(expression, selector) {
this.expression = expression;
this.selector = selector;
}
function handleOnError(o) { return function (e) { o.onError(e); }; }
function handleOnNext(self, observer) {
return function onNext () {
var result = tryCatch(self.selector).apply(self, arguments);
if (result === errorObj) { return observer.onError(result.e); }
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [], errHandler = handleOnError(observer);
for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this.joinObserverArray = joinObserverArray;
this.onNext = onNext;
this.onCompleted = onCompleted;
this.joinObservers = new Map();
for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
var joinObserver = this.joinObserverArray[i];
this.joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this.joinObservers.forEach(function (v) { v.queue.shift(); });
};
ActivePlan.prototype.match = function () {
var i, len, hasValues = true;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
if (this.joinObserverArray[i].queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
firstValues.push(this.joinObserverArray[i].queue[0]);
this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this.onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this.onNext.apply(this, values);
}
}
};
var JoinObserver = (function (__super__) {
inherits(JoinObserver, __super__);
function JoinObserver(source, onError) {
__super__.call(this);
this.source = source;
this.onError = onError;
this.queue = [];
this.activePlans = [];
this.subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
var JoinObserverPrototype = JoinObserver.prototype;
JoinObserverPrototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this.onError(notification.error);
}
this.queue.push(notification);
var activePlans = this.activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserverPrototype.error = noop;
JoinObserverPrototype.completed = noop;
JoinObserverPrototype.addActivePlan = function (activePlan) {
this.activePlans.push(activePlan);
};
JoinObserverPrototype.subscribe = function () {
this.subscription.setDisposable(this.source.materialize().subscribe(this));
};
JoinObserverPrototype.removeActivePlan = function (activePlan) {
this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
this.activePlans.length === 0 && this.dispose();
};
JoinObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this.subscription.dispose();
}
};
return JoinObserver;
} (AbstractObserver));
/**
* Creates a pattern that matches when both observable sequences have an available value.
*
* @param right Observable sequence to match with the current sequence.
* @return {Pattern} Pattern object that matches when both observable sequences have an available value.
*/
observableProto.and = function (right) {
return new Pattern([this, right]);
};
/**
* Matches when the observable sequence has an available value and projects the value.
*
* @param {Function} selector Selector that will be invoked for values in the source sequence.
* @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
observableProto.thenDo = function (selector) {
return new Pattern([this]).thenDo(selector);
};
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
Observable.when = function () {
var len = arguments.length, plans;
if (Array.isArray(arguments[0])) {
plans = arguments[0];
} else {
plans = new Array(len);
for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
}
return new AnonymousObservable(function (o) {
var activePlans = [],
externalSubscriptions = new Map();
var outObserver = observerCreate(
function (x) { o.onNext(x); },
function (err) {
externalSubscriptions.forEach(function (v) { v.onError(err); });
o.onError(err);
},
function (x) { o.onCompleted(); }
);
try {
for (var i = 0, len = plans.length; i < len; i++) {
activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return observableThrow(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
});
};
var TimerObservable = (function(__super__) {
inherits(TimerObservable, __super__);
function TimerObservable(dt, s) {
this._dt = dt;
this._s = s;
__super__.call(this);
}
TimerObservable.prototype.subscribeCore = function (o) {
return this._s.scheduleFuture(o, this._dt, scheduleMethod);
};
function scheduleMethod(s, o) {
o.onNext(0);
o.onCompleted();
}
return TimerObservable;
}(ObservableBase));
function _observableTimer(dueTime, scheduler) {
return new TimerObservable(dueTime, scheduler);
}
function observableTimerDateAndPeriod(dueTime, period, scheduler) {
return new AnonymousObservable(function (observer) {
var d = dueTime, p = normalizeTime(period);
return scheduler.scheduleRecursiveFuture(0, d, function (count, self) {
if (p > 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
* @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTime = observableProto.windowTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
var source = this, timeShift;
timeShiftOrScheduler == null && (timeShift = timeSpan);
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (typeof timeShiftOrScheduler === 'number') {
timeShift = timeShiftOrScheduler;
} else if (isScheduler(timeShiftOrScheduler)) {
timeShift = timeSpan;
scheduler = timeShiftOrScheduler;
}
return new AnonymousObservable(function (observer) {
var groupDisposable,
nextShift = timeShift,
nextSpan = timeSpan,
q = [],
refCountDisposable,
timerD = new SerialDisposable(),
totalTime = 0;
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable);
function createTimer () {
var m = new SingleAssignmentDisposable(),
isSpan = false,
isShift = false;
timerD.setDisposable(m);
if (nextSpan === nextShift) {
isSpan = true;
isShift = true;
} else if (nextSpan < nextShift) {
isSpan = true;
} else {
isShift = true;
}
var newTotalTime = isSpan ? nextSpan : nextShift,
ts = newTotalTime - totalTime;
totalTime = newTotalTime;
if (isSpan) {
nextSpan += timeShift;
}
if (isShift) {
nextShift += timeShift;
}
m.setDisposable(scheduler.scheduleFuture(null, ts, function () {
if (isShift) {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
isSpan && q.shift().onCompleted();
createTimer();
}));
};
q.push(new Subject());
observer.onNext(addRef(q[0], refCountDisposable));
createTimer();
groupDisposable.add(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
},
function (e) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onError(e); }
observer.onError(e);
},
function () {
for (var i = 0, len = q.length; i < len; i++) { q[i].onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
/**
* Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a window.
* @param {Number} count Maximum element count of a window.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTimeOrCount = observableProto.windowTimeOrCount = function (timeSpan, count, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (observer) {
var timerD = new SerialDisposable(),
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable),
n = 0,
windowId = 0,
s = new Subject();
function createTimer(id) {
var m = new SingleAssignmentDisposable();
timerD.setDisposable(m);
m.setDisposable(scheduler.scheduleFuture(null, timeSpan, function () {
if (id !== windowId) { return; }
n = 0;
var newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
createTimer(newId);
}));
}
observer.onNext(addRef(s, refCountDisposable));
createTimer(0);
groupDisposable.add(source.subscribe(
function (x) {
var newId = 0, newWindow = false;
s.onNext(x);
if (++n === count) {
newWindow = true;
n = 0;
newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
}
newWindow && createTimer(newId);
},
function (e) {
s.onError(e);
observer.onError(e);
}, function () {
s.onCompleted();
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
* @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
* @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTime = observableProto.bufferTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
return this.windowWithTime(timeSpan, timeShiftOrScheduler, scheduler).flatMap(toArray);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a buffer.
* @param {Number} count Maximum element count of a buffer.
* @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTimeOrCount = observableProto.bufferTimeOrCount = function (timeSpan, count, scheduler) {
return this.windowWithTimeOrCount(timeSpan, count, scheduler).flatMap(toArray);
};
var TimeIntervalObservable = (function (__super__) {
inherits(TimeIntervalObservable, __super__);
function TimeIntervalObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimeIntervalObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimeIntervalObserver(o, this._s));
};
return TimeIntervalObservable;
}(ObservableBase));
var TimeIntervalObserver = (function (__super__) {
inherits(TimeIntervalObserver, __super__);
function TimeIntervalObserver(o, s) {
this._o = o;
this._s = s;
this._l = s.now();
__super__.call(this);
}
TimeIntervalObserver.prototype.next = function (x) {
var now = this._s.now(), span = now - this._l;
this._l = now;
this._o.onNext({ value: x, interval: span });
};
TimeIntervalObserver.prototype.error = function (e) { this._o.onError(e); };
TimeIntervalObserver.prototype.completed = function () { this._o.onCompleted(); };
return TimeIntervalObserver;
}(AbstractObserver));
/**
* Records the time interval between consecutive values in an observable sequence.
*
* @example
* 1 - res = source.timeInterval();
* 2 - res = source.timeInterval(Rx.Scheduler.timeout);
*
* @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence with time interval information on values.
*/
observableProto.timeInterval = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimeIntervalObservable(this, scheduler);
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
var GenerateAbsoluteObservable = (function (__super__) {
inherits(GenerateAbsoluteObservable, __super__);
function GenerateAbsoluteObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateAbsoluteObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, new Date(this._s.now()), scheduleRecursive);
};
return GenerateAbsoluteObservable;
}(ObservableBase));
/**
* GenerateAbsolutes an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithAbsoluteTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return new Date(); }
* });
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateAbsoluteObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var GenerateRelativeObservable = (function (__super__) {
inherits(GenerateRelativeObservable, __super__);
function GenerateRelativeObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateRelativeObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, 0, scheduleRecursive);
};
return GenerateRelativeObservable;
}(ObservableBase));
/**
* Generates an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithRelativeTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return 500; }
* );
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateRelativeObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var DelaySubscription = (function(__super__) {
inherits(DelaySubscription, __super__);
function DelaySubscription(source, dt, s) {
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DelaySubscription.prototype.subscribeCore = function (o) {
var d = new SerialDisposable();
d.setDisposable(this._s.scheduleFuture([this.source, o, d], this._dt, scheduleMethod));
return d;
};
function scheduleMethod(s, state) {
var source = state[0], o = state[1], d = state[2];
d.setDisposable(source.subscribe(o));
}
return DelaySubscription;
}(ObservableBase));
/**
* Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.delaySubscription(5000); // 5s
* 2 - res = source.delaySubscription(5000, Rx.Scheduler.default); // 5 seconds
*
* @param {Number} dueTime Relative or absolute time shift of the subscription.
* @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delaySubscription = function (dueTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new DelaySubscription(this, dueTime, scheduler);
};
var SkipLastWithTimeObservable = (function (__super__) {
inherits(SkipLastWithTimeObservable, __super__);
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
return SkipLastWithTimeObservable;
}(ObservableBase));
var SkipLastWithTimeObserver = (function (__super__) {
inherits(SkipLastWithTimeObserver, __super__);
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
__super__.call(this);
}
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
return SkipLastWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for skipping elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
*/
observableProto.skipLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipLastWithTimeObservable(this, duration, scheduler);
};
var TakeLastWithTimeObservable = (function (__super__) {
inherits(TakeLastWithTimeObservable, __super__);
function TakeLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
TakeLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeLastWithTimeObserver(o, this._d, this._s));
};
return TakeLastWithTimeObservable;
}(ObservableBase));
var TakeLastWithTimeObserver = (function (__super__) {
inherits(TakeLastWithTimeObserver, __super__);
function TakeLastWithTimeObserver(o, d, s) {
this._o = o;
this._d = d;
this._s = s;
this._q = [];
__super__.call(this);
}
TakeLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._q.shift();
}
};
TakeLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0) {
var next = this._q.shift();
if (now - next.interval <= this._d) { this._o.onNext(next.value); }
}
this._o.onCompleted();
};
return TakeLastWithTimeObserver;
}(AbstractObserver));
/**
* Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeLastWithTimeObservable(this, duration, scheduler);
};
/**
* Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastBufferWithTime = function (duration, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (o) {
var q = [];
return source.subscribe(function (x) {
var now = scheduler.now();
q.push({ interval: now, value: x });
while (q.length > 0 && now - q[0].interval >= duration) {
q.shift();
}
}, function (e) { o.onError(e); }, function () {
var now = scheduler.now(), res = [];
while (q.length > 0) {
var next = q.shift();
now - next.interval <= duration && res.push(next.value);
}
o.onNext(res);
o.onCompleted();
});
}, source);
};
var TakeWithTimeObservable = (function (__super__) {
inherits(TakeWithTimeObservable, __super__);
function TakeWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
function scheduleMethod(s, o) {
o.onCompleted();
}
TakeWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(o, this._d, scheduleMethod),
this.source.subscribe(o)
);
};
return TakeWithTimeObservable;
}(ObservableBase));
/**
* Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.takeWithTime(5000, [optional scheduler]);
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
*/
observableProto.takeWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeWithTimeObservable(this, duration, scheduler);
};
var SkipWithTimeObservable = (function (__super__) {
inherits(SkipWithTimeObservable, __super__);
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
__super__.call(this);
}
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
return SkipWithTimeObservable;
}(ObservableBase));
var SkipWithTimeObserver = (function (__super__) {
inherits(SkipWithTimeObserver, __super__);
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
* @description
* Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
* This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
* may not execute immediately, despite the zero due time.
*
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
* @param {Number} duration Duration for skipping elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
*/
observableProto.skipWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipWithTimeObservable(this, duration, scheduler);
};
var SkipUntilWithTimeObservable = (function (__super__) {
inherits(SkipUntilWithTimeObservable, __super__);
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
__super__.call(this);
}
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
return SkipUntilWithTimeObservable;
}(ObservableBase));
var SkipUntilWithTimeObserver = (function (__super__) {
inherits(SkipUntilWithTimeObserver, __super__);
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipUntilWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
*
* @examples
* 1 - res = source.skipUntilWithTime(new Date(), [scheduler]);
* 2 - res = source.skipUntilWithTime(5000, [scheduler]);
* @param {Date|Number} startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped until the specified start time.
*/
observableProto.skipUntilWithTime = function (startTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipUntilWithTimeObservable(this, startTime, scheduler);
};
/**
* Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
* @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
* @param {Scheduler} [scheduler] Scheduler to run the timer on.
* @returns {Observable} An observable sequence with the elements taken until the specified end time.
*/
observableProto.takeUntilWithTime = function (endTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var source = this;
return new AnonymousObservable(function (o) {
return new BinaryDisposable(
scheduler.scheduleFuture(o, endTime, function (_, o) { o.onCompleted(); }),
source.subscribe(o));
}, source);
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
var SwitchFirstObservable = (function (__super__) {
inherits(SwitchFirstObservable, __super__);
function SwitchFirstObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
return SwitchFirstObservable;
}(ObservableBase));
var SwitchFirstObserver = (function(__super__) {
inherits(SwitchFirstObserver, __super__);
function SwitchFirstObserver(state) {
this._s = state;
__super__.call(this);
}
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = observableFromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
inherits(InnerObserver, __super__);
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
return SwitchFirstObserver;
}(AbstractObserver));
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
observableProto.switchFirst = function () {
return new SwitchFirstObservable(this);
};
observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
};
observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
/** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
Rx.HistoricalScheduler = (function (__super__) {
inherits(HistoricalScheduler, __super__);
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function HistoricalScheduler(initialClock, comparer) {
var clock = initialClock == null ? 0 : initialClock;
var cmp = comparer || defaultSubComparer;
__super__.call(this, clock, cmp);
}
var HistoricalSchedulerProto = HistoricalScheduler.prototype;
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
HistoricalSchedulerProto.add = function (absolute, relative) {
return absolute + relative;
};
HistoricalSchedulerProto.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
* @memberOf HistoricalScheduler
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
HistoricalSchedulerProto.toRelativeTime = function (timeSpan) {
return timeSpan;
};
return HistoricalScheduler;
}(Rx.VirtualTimeScheduler));
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var UnderlyingObservable = (function (__super__) {
inherits(UnderlyingObservable, __super__);
function UnderlyingObservable(m, u) {
this._m = m;
this._u = u;
__super__.call(this);
}
UnderlyingObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._m.getDisposable(), this._u.subscribe(o));
};
return UnderlyingObservable;
}(ObservableBase));
var GroupedObservable = (function (__super__) {
inherits(GroupedObservable, __super__);
function GroupedObservable(key, underlyingObservable, mergedDisposable) {
__super__.call(this);
this.key = key;
this.underlyingObservable = !mergedDisposable ?
underlyingObservable :
new UnderlyingObservable(mergedDisposable, underlyingObservable);
}
GroupedObservable.prototype._subscribe = function (o) {
return this.underlyingObservable.subscribe(o);
};
return GroupedObservable;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: dist/rx.all.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) { for(var a = [], i = 0, len = arr.length; i < len; i++) { a.push(arr[i]); } return a;}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
schedulerProto.catchError = schedulerProto['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
var CatchScheduler = (function (__super__) {
inherits(CatchScheduler, __super__);
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
__super__.call(this);
}
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () { return this._scheduler.now(); };
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) { thrower(res.e); }
return disposableEmpty;
}
return disposableFixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this, failed = false, d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) { return null; }
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) { thrower(res.e); }
d.dispose();
return null;
}
return res;
}));
return d;
};
return CatchScheduler;
}(Scheduler));
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var self = this;
return new AnonymousObserver(
function (x) { self.onNext(x); },
function (err) { self.onError(err); },
function () { self.onCompleted(); });
};
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var cb = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return cb(notificationCreateOnNext(x));
}, function (e) {
return cb(notificationCreateOnError(e));
}, function () {
return cb(notificationCreateOnCompleted());
});
};
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.prototype.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
Observer.prototype.makeSafe = function(disposable) {
return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var FromPromiseObservable = (function(__super__) {
inherits(FromPromiseObservable, __super__);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
__super__.call(this);
}
function scheduleNext(s, state) {
var o = state[0], data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0], err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function(o) {
var sad = new SingleAssignmentDisposable(), self = this, p = this._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p
.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
return FromPromiseObservable;
}(ObservableBase));
/**
* Converts a Promise to an Observable sequence
* @param {Promise} An ES6 Compliant promise.
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
var observableFromPromise = Observable.fromPromise = function (promise, scheduler) {
scheduler || (scheduler = defaultScheduler);
return new FromPromiseObservable(promise, scheduler);
};
/*
* Converts an existing observable sequence to an ES6 Compatible Promise
* @example
* var promise = Rx.Observable.return(42).toPromise(RSVP.Promise);
*
* // With config
* Rx.config.Promise = RSVP.Promise;
* var promise = Rx.Observable.return(42).toPromise();
* @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise.
* @returns {Promise} An ES6 compatible promise with the last value from the observable sequence.
*/
observableProto.toPromise = function (promiseCtor) {
promiseCtor || (promiseCtor = Rx.config.Promise);
if (!promiseCtor) { throw new NotSupportedError('Promise type not provided nor in Rx.config.Promise'); }
var source = this;
return new promiseCtor(function (resolve, reject) {
// No cancellation can be done
var value;
source.subscribe(function (v) {
value = v;
}, reject, function () {
resolve(value);
});
});
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
/**
* Creates an Observable sequence from changes to an array using Array.observe.
* @param {Array} array An array to observe changes.
* @returns {Observable} An observable sequence containing changes to an array from Array.observe.
*/
Observable.ofArrayChanges = function(array) {
if (!Array.isArray(array)) { throw new TypeError('Array.observe only accepts arrays.'); }
if (typeof Array.observe !== 'function' && typeof Array.unobserve !== 'function') { throw new TypeError('Array.observe is not supported on your platform') }
return new AnonymousObservable(function(observer) {
function observerFn(changes) {
for(var i = 0, len = changes.length; i < len; i++) {
observer.onNext(changes[i]);
}
}
Array.observe(array, observerFn);
return function () {
Array.unobserve(array, observerFn);
};
});
};
/**
* Creates an Observable sequence from changes to an object using Object.observe.
* @param {Object} obj An object to observe changes.
* @returns {Observable} An observable sequence containing changes to an object from Object.observe.
*/
Observable.ofObjectChanges = function(obj) {
if (obj == null) { throw new TypeError('object must not be null or undefined.'); }
if (typeof Object.observe !== 'function' && typeof Object.unobserve !== 'function') { throw new TypeError('Object.observe is not supported on your platform') }
return new AnonymousObservable(function(observer) {
function observerFn(changes) {
for(var i = 0, len = changes.length; i < len; i++) {
observer.onNext(changes[i]);
}
}
Object.observe(obj, observerFn);
return function () {
Object.unobserve(obj, observerFn);
};
});
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
function concatMap(source, selector, thisArg) {
var selectorFunc = bindCallback(selector, thisArg, 3);
return source.map(function (x, i) {
var result = selectorFunc(x, i, source);
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = observableFrom(result));
return result;
}).concatAll();
}
/**
* One of the Following:
* Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
*
* @example
* var res = source.concatMap(function (x) { return Rx.Observable.range(0, x); });
* Or:
* Projects each element of an observable sequence to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
*
* var res = source.concatMap(function (x) { return Rx.Observable.range(0, x); }, function (x, y) { return x + y; });
* Or:
* Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence.
*
* var res = source.concatMap(Rx.Observable.fromArray([1,2,3]));
* @param {Function} selector A transform function to apply to each element or an observable sequence to project each element from the
* source sequence onto which could be either an observable or Promise.
* @param {Function} [resultSelector] A transform function to apply to each element of the intermediate sequence.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
*/
observableProto.selectConcat = observableProto.concatMap = function (selector, resultSelector, thisArg) {
if (isFunction(selector) && isFunction(resultSelector)) {
return this.concatMap(function (x, i) {
var selectorResult = selector(x, i);
isPromise(selectorResult) && (selectorResult = observableFromPromise(selectorResult));
(isArrayLike(selectorResult) || isIterable(selectorResult)) && (selectorResult = observableFrom(selectorResult));
return selectorResult.map(function (y, i2) {
return resultSelector(x, y, i, i2);
});
});
}
return isFunction(selector) ?
concatMap(this, selector, thisArg) :
concatMap(this, function () { return selector; });
};
/**
* Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.concatMapObserver = observableProto.selectConcatObserver = function(onNext, onError, onCompleted, thisArg) {
var source = this,
onNextFunc = bindCallback(onNext, thisArg, 2),
onErrorFunc = bindCallback(onError, thisArg, 1),
onCompletedFunc = bindCallback(onCompleted, thisArg, 0);
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNextFunc(x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onErrorFunc(err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompletedFunc();
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, this).concatAll();
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
*
* @example
* var res = observable.groupBy(function (x) { return x.id; });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} [elementSelector] A function to map each source element to an element in an observable group.
* @returns {Observable} A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
*/
observableProto.groupBy = function (keySelector, elementSelector) {
return this.groupByUntil(keySelector, elementSelector, observableNever);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function.
* A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
* key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
*
* @example
* var res = observable.groupByUntil(function (x) { return x.id; }, null, function () { return Rx.Observable.never(); });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} durationSelector A function to signal the expiration of a group.
* @returns {Observable}
* A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
* If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
*
*/
observableProto.groupByUntil = function (keySelector, elementSelector, durationSelector) {
var source = this;
return new AnonymousObservable(function (o) {
var map = new Map(),
groupDisposable = new CompositeDisposable(),
refCountDisposable = new RefCountDisposable(groupDisposable),
handleError = function (e) { return function (item) { item.onError(e); }; };
groupDisposable.add(
source.subscribe(function (x) {
var key = tryCatch(keySelector)(x);
if (key === errorObj) {
map.forEach(handleError(key.e));
return o.onError(key.e);
}
var fireNewMapEntry = false, writer = map.get(key);
if (writer === undefined) {
writer = new Subject();
map.set(key, writer);
fireNewMapEntry = true;
}
if (fireNewMapEntry) {
var group = new GroupedObservable(key, writer, refCountDisposable),
durationGroup = new GroupedObservable(key, writer);
var duration = tryCatch(durationSelector)(durationGroup);
if (duration === errorObj) {
map.forEach(handleError(duration.e));
return o.onError(duration.e);
}
o.onNext(group);
var md = new SingleAssignmentDisposable();
groupDisposable.add(md);
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
map.forEach(handleError(e));
o.onError(e);
},
function () {
if (map['delete'](key)) { writer.onCompleted(); }
groupDisposable.remove(md);
}));
}
var element = x;
if (isFunction(elementSelector)) {
element = tryCatch(elementSelector)(x);
if (element === errorObj) {
map.forEach(handleError(element.e));
return o.onError(element.e);
}
}
writer.onNext(element);
}, function (e) {
map.forEach(handleError(e));
o.onError(e);
}, function () {
map.forEach(function (item) { item.onCompleted(); });
o.onCompleted();
}));
return refCountDisposable;
}, source);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
/**
* Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.flatMapObserver = observableProto.selectManyObserver = function (onNext, onError, onCompleted, thisArg) {
var source = this;
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNext.call(thisArg, x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onError.call(thisArg, err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompleted.call(thisArg);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, source).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
work = state.q.shift();
} else {
state.isAcquired = false;
return;
}
var m1 = new SingleAssignmentDisposable();
state.d.add(m1);
m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
recurse([state, self]);
}
ExpandObservable.prototype._ensureActive = function (state) {
var isOwner = false;
if (state.q.length > 0) {
isOwner = !state.isAcquired;
state.isAcquired = true;
}
isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
};
ExpandObservable.prototype.subscribeCore = function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
state = {
q: [],
m: m,
d: d,
activeCount: 0,
isAcquired: false,
o: o
};
state.q.push(this.source);
state.activeCount++;
this._ensureActive(state);
return d;
};
return ExpandObservable;
}(ObservableBase));
var ExpandObserver = (function(__super__) {
inherits(ExpandObserver, __super__);
function ExpandObserver(state, parent, m1) {
this._s = state;
this._p = parent;
this._m1 = m1;
__super__.call(this);
}
ExpandObserver.prototype.next = function (x) {
this._s.o.onNext(x);
var result = tryCatch(this._p._fn)(x);
if (result === errorObj) { return this._s.o.onError(result.e); }
this._s.q.push(result);
this._s.activeCount++;
this._p._ensureActive(this._s);
};
ExpandObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ExpandObserver.prototype.completed = function () {
this._s.d.remove(this._m1);
this._s.activeCount--;
this._s.activeCount === 0 && this._s.o.onCompleted();
};
return ExpandObserver;
}(AbstractObserver));
/**
* Expands an observable sequence by recursively invoking selector.
*
* @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
* @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
* @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
*/
observableProto.expand = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new ExpandObservable(this, selector, scheduler);
};
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ForkJoinObservable = (function (__super__) {
inherits(ForkJoinObservable, __super__);
function ForkJoinObservable(sources, cb) {
this._sources = sources;
this._cb = cb;
__super__.call(this);
}
ForkJoinObservable.prototype.subscribeCore = function (o) {
if (this._sources.length === 0) {
o.onCompleted();
return disposableEmpty;
}
var count = this._sources.length;
var state = {
finished: false,
hasResults: new Array(count),
hasCompleted: new Array(count),
results: new Array(count)
};
var subscriptions = new CompositeDisposable();
for (var i = 0, len = this._sources.length; i < len; i++) {
var source = this._sources[i];
isPromise(source) && (source = observableFromPromise(source));
subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
}
return subscriptions;
};
return ForkJoinObservable;
}(ObservableBase));
var ForkJoinObserver = (function(__super__) {
inherits(ForkJoinObserver, __super__);
function ForkJoinObserver(o, s, i, cb, subs) {
this._o = o;
this._s = s;
this._i = i;
this._cb = cb;
this._subs = subs;
__super__.call(this);
}
ForkJoinObserver.prototype.next = function (x) {
if (!this._s.finished) {
this._s.hasResults[this._i] = true;
this._s.results[this._i] = x;
}
};
ForkJoinObserver.prototype.error = function (e) {
this._s.finished = true;
this._o.onError(e);
this._subs.dispose();
};
ForkJoinObserver.prototype.completed = function () {
if (!this._s.finished) {
if (!this._s.hasResults[this._i]) {
return this._o.onCompleted();
}
this._s.hasCompleted[this._i] = true;
for (var i = 0; i < this._s.results.length; i++) {
if (!this._s.hasCompleted[i]) { return; }
}
this._s.finished = true;
var res = tryCatch(this._cb).apply(null, this._s.results);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
this._o.onCompleted();
}
};
return ForkJoinObserver;
}(AbstractObserver));
/**
* Runs all observable sequences in parallel and collect their last elements.
*
* @example
* 1 - res = Rx.Observable.forkJoin([obs1, obs2]);
* 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...);
* @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences.
*/
Observable.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new ForkJoinObservable(args, resultSelector);
};
/**
* Runs two observable sequences in parallel and combines their last elemenets.
* @param {Observable} second Second observable sequence.
* @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences.
* @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences.
*/
observableProto.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return Observable.forkJoin.apply(null, args);
};
/**
* Comonadic bind operator.
* @param {Function} selector A transform function to apply to each element.
* @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
* @returns {Observable} An observable sequence which results from the comonadic bind operation.
*/
observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
var source = this;
return observableDefer(function () {
var chain;
return source
.map(function (x) {
var curr = new ChainObservable(x);
chain && chain.onNext(x);
chain = curr;
return curr;
})
.tap(
noop,
function (e) { chain && chain.onError(e); },
function () { chain && chain.onCompleted(); }
)
.observeOn(scheduler)
.map(selector);
}, source);
};
var ChainObservable = (function (__super__) {
inherits(ChainObservable, __super__);
function ChainObservable(head) {
__super__.call(this);
this.head = head;
this.tail = new AsyncSubject();
}
addProperties(ChainObservable.prototype, Observer, {
_subscribe: function (o) {
var g = new CompositeDisposable();
g.add(currentThreadScheduler.schedule(this, function (_, self) {
o.onNext(self.head);
g.add(self.tail.mergeAll().subscribe(o));
}));
return g;
},
onCompleted: function () {
this.onNext(Observable.empty());
},
onError: function (e) {
this.onNext(Observable['throw'](e));
},
onNext: function (v) {
this.tail.onNext(v);
this.tail.onCompleted();
}
});
return ChainObservable;
}(Observable));
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this.patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this.patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
function Plan(expression, selector) {
this.expression = expression;
this.selector = selector;
}
function handleOnError(o) { return function (e) { o.onError(e); }; }
function handleOnNext(self, observer) {
return function onNext () {
var result = tryCatch(self.selector).apply(self, arguments);
if (result === errorObj) { return observer.onError(result.e); }
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [], errHandler = handleOnError(observer);
for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this.joinObserverArray = joinObserverArray;
this.onNext = onNext;
this.onCompleted = onCompleted;
this.joinObservers = new Map();
for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
var joinObserver = this.joinObserverArray[i];
this.joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this.joinObservers.forEach(function (v) { v.queue.shift(); });
};
ActivePlan.prototype.match = function () {
var i, len, hasValues = true;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
if (this.joinObserverArray[i].queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
firstValues.push(this.joinObserverArray[i].queue[0]);
this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this.onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this.onNext.apply(this, values);
}
}
};
var JoinObserver = (function (__super__) {
inherits(JoinObserver, __super__);
function JoinObserver(source, onError) {
__super__.call(this);
this.source = source;
this.onError = onError;
this.queue = [];
this.activePlans = [];
this.subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
var JoinObserverPrototype = JoinObserver.prototype;
JoinObserverPrototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this.onError(notification.error);
}
this.queue.push(notification);
var activePlans = this.activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserverPrototype.error = noop;
JoinObserverPrototype.completed = noop;
JoinObserverPrototype.addActivePlan = function (activePlan) {
this.activePlans.push(activePlan);
};
JoinObserverPrototype.subscribe = function () {
this.subscription.setDisposable(this.source.materialize().subscribe(this));
};
JoinObserverPrototype.removeActivePlan = function (activePlan) {
this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
this.activePlans.length === 0 && this.dispose();
};
JoinObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this.subscription.dispose();
}
};
return JoinObserver;
} (AbstractObserver));
/**
* Creates a pattern that matches when both observable sequences have an available value.
*
* @param right Observable sequence to match with the current sequence.
* @return {Pattern} Pattern object that matches when both observable sequences have an available value.
*/
observableProto.and = function (right) {
return new Pattern([this, right]);
};
/**
* Matches when the observable sequence has an available value and projects the value.
*
* @param {Function} selector Selector that will be invoked for values in the source sequence.
* @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
observableProto.thenDo = function (selector) {
return new Pattern([this]).thenDo(selector);
};
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
Observable.when = function () {
var len = arguments.length, plans;
if (Array.isArray(arguments[0])) {
plans = arguments[0];
} else {
plans = new Array(len);
for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
}
return new AnonymousObservable(function (o) {
var activePlans = [],
externalSubscriptions = new Map();
var outObserver = observerCreate(
function (x) { o.onNext(x); },
function (err) {
externalSubscriptions.forEach(function (v) { v.onError(err); });
o.onError(err);
},
function (x) { o.onCompleted(); }
);
try {
for (var i = 0, len = plans.length; i < len; i++) {
activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return observableThrow(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
});
};
var TimerObservable = (function(__super__) {
inherits(TimerObservable, __super__);
function TimerObservable(dt, s) {
this._dt = dt;
this._s = s;
__super__.call(this);
}
TimerObservable.prototype.subscribeCore = function (o) {
return this._s.scheduleFuture(o, this._dt, scheduleMethod);
};
function scheduleMethod(s, o) {
o.onNext(0);
o.onCompleted();
}
return TimerObservable;
}(ObservableBase));
function _observableTimer(dueTime, scheduler) {
return new TimerObservable(dueTime, scheduler);
}
function observableTimerDateAndPeriod(dueTime, period, scheduler) {
return new AnonymousObservable(function (observer) {
var d = dueTime, p = normalizeTime(period);
return scheduler.scheduleRecursiveFuture(0, d, function (count, self) {
if (p > 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
* @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTime = observableProto.windowTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
var source = this, timeShift;
timeShiftOrScheduler == null && (timeShift = timeSpan);
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (typeof timeShiftOrScheduler === 'number') {
timeShift = timeShiftOrScheduler;
} else if (isScheduler(timeShiftOrScheduler)) {
timeShift = timeSpan;
scheduler = timeShiftOrScheduler;
}
return new AnonymousObservable(function (observer) {
var groupDisposable,
nextShift = timeShift,
nextSpan = timeSpan,
q = [],
refCountDisposable,
timerD = new SerialDisposable(),
totalTime = 0;
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable);
function createTimer () {
var m = new SingleAssignmentDisposable(),
isSpan = false,
isShift = false;
timerD.setDisposable(m);
if (nextSpan === nextShift) {
isSpan = true;
isShift = true;
} else if (nextSpan < nextShift) {
isSpan = true;
} else {
isShift = true;
}
var newTotalTime = isSpan ? nextSpan : nextShift,
ts = newTotalTime - totalTime;
totalTime = newTotalTime;
if (isSpan) {
nextSpan += timeShift;
}
if (isShift) {
nextShift += timeShift;
}
m.setDisposable(scheduler.scheduleFuture(null, ts, function () {
if (isShift) {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
isSpan && q.shift().onCompleted();
createTimer();
}));
};
q.push(new Subject());
observer.onNext(addRef(q[0], refCountDisposable));
createTimer();
groupDisposable.add(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
},
function (e) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onError(e); }
observer.onError(e);
},
function () {
for (var i = 0, len = q.length; i < len; i++) { q[i].onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
/**
* Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a window.
* @param {Number} count Maximum element count of a window.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTimeOrCount = observableProto.windowTimeOrCount = function (timeSpan, count, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (observer) {
var timerD = new SerialDisposable(),
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable),
n = 0,
windowId = 0,
s = new Subject();
function createTimer(id) {
var m = new SingleAssignmentDisposable();
timerD.setDisposable(m);
m.setDisposable(scheduler.scheduleFuture(null, timeSpan, function () {
if (id !== windowId) { return; }
n = 0;
var newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
createTimer(newId);
}));
}
observer.onNext(addRef(s, refCountDisposable));
createTimer(0);
groupDisposable.add(source.subscribe(
function (x) {
var newId = 0, newWindow = false;
s.onNext(x);
if (++n === count) {
newWindow = true;
n = 0;
newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
}
newWindow && createTimer(newId);
},
function (e) {
s.onError(e);
observer.onError(e);
}, function () {
s.onCompleted();
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
* @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
* @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTime = observableProto.bufferTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
return this.windowWithTime(timeSpan, timeShiftOrScheduler, scheduler).flatMap(toArray);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a buffer.
* @param {Number} count Maximum element count of a buffer.
* @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTimeOrCount = observableProto.bufferTimeOrCount = function (timeSpan, count, scheduler) {
return this.windowWithTimeOrCount(timeSpan, count, scheduler).flatMap(toArray);
};
var TimeIntervalObservable = (function (__super__) {
inherits(TimeIntervalObservable, __super__);
function TimeIntervalObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimeIntervalObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimeIntervalObserver(o, this._s));
};
return TimeIntervalObservable;
}(ObservableBase));
var TimeIntervalObserver = (function (__super__) {
inherits(TimeIntervalObserver, __super__);
function TimeIntervalObserver(o, s) {
this._o = o;
this._s = s;
this._l = s.now();
__super__.call(this);
}
TimeIntervalObserver.prototype.next = function (x) {
var now = this._s.now(), span = now - this._l;
this._l = now;
this._o.onNext({ value: x, interval: span });
};
TimeIntervalObserver.prototype.error = function (e) { this._o.onError(e); };
TimeIntervalObserver.prototype.completed = function () { this._o.onCompleted(); };
return TimeIntervalObserver;
}(AbstractObserver));
/**
* Records the time interval between consecutive values in an observable sequence.
*
* @example
* 1 - res = source.timeInterval();
* 2 - res = source.timeInterval(Rx.Scheduler.timeout);
*
* @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence with time interval information on values.
*/
observableProto.timeInterval = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimeIntervalObservable(this, scheduler);
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
var GenerateAbsoluteObservable = (function (__super__) {
inherits(GenerateAbsoluteObservable, __super__);
function GenerateAbsoluteObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateAbsoluteObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, new Date(this._s.now()), scheduleRecursive);
};
return GenerateAbsoluteObservable;
}(ObservableBase));
/**
* GenerateAbsolutes an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithAbsoluteTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return new Date(); }
* });
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateAbsoluteObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var GenerateRelativeObservable = (function (__super__) {
inherits(GenerateRelativeObservable, __super__);
function GenerateRelativeObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateRelativeObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, 0, scheduleRecursive);
};
return GenerateRelativeObservable;
}(ObservableBase));
/**
* Generates an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithRelativeTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return 500; }
* );
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateRelativeObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var DelaySubscription = (function(__super__) {
inherits(DelaySubscription, __super__);
function DelaySubscription(source, dt, s) {
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DelaySubscription.prototype.subscribeCore = function (o) {
var d = new SerialDisposable();
d.setDisposable(this._s.scheduleFuture([this.source, o, d], this._dt, scheduleMethod));
return d;
};
function scheduleMethod(s, state) {
var source = state[0], o = state[1], d = state[2];
d.setDisposable(source.subscribe(o));
}
return DelaySubscription;
}(ObservableBase));
/**
* Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.delaySubscription(5000); // 5s
* 2 - res = source.delaySubscription(5000, Rx.Scheduler.default); // 5 seconds
*
* @param {Number} dueTime Relative or absolute time shift of the subscription.
* @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delaySubscription = function (dueTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new DelaySubscription(this, dueTime, scheduler);
};
var SkipLastWithTimeObservable = (function (__super__) {
inherits(SkipLastWithTimeObservable, __super__);
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
return SkipLastWithTimeObservable;
}(ObservableBase));
var SkipLastWithTimeObserver = (function (__super__) {
inherits(SkipLastWithTimeObserver, __super__);
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
__super__.call(this);
}
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
return SkipLastWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for skipping elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
*/
observableProto.skipLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipLastWithTimeObservable(this, duration, scheduler);
};
var TakeLastWithTimeObservable = (function (__super__) {
inherits(TakeLastWithTimeObservable, __super__);
function TakeLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
TakeLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeLastWithTimeObserver(o, this._d, this._s));
};
return TakeLastWithTimeObservable;
}(ObservableBase));
var TakeLastWithTimeObserver = (function (__super__) {
inherits(TakeLastWithTimeObserver, __super__);
function TakeLastWithTimeObserver(o, d, s) {
this._o = o;
this._d = d;
this._s = s;
this._q = [];
__super__.call(this);
}
TakeLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._q.shift();
}
};
TakeLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0) {
var next = this._q.shift();
if (now - next.interval <= this._d) { this._o.onNext(next.value); }
}
this._o.onCompleted();
};
return TakeLastWithTimeObserver;
}(AbstractObserver));
/**
* Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeLastWithTimeObservable(this, duration, scheduler);
};
/**
* Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastBufferWithTime = function (duration, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (o) {
var q = [];
return source.subscribe(function (x) {
var now = scheduler.now();
q.push({ interval: now, value: x });
while (q.length > 0 && now - q[0].interval >= duration) {
q.shift();
}
}, function (e) { o.onError(e); }, function () {
var now = scheduler.now(), res = [];
while (q.length > 0) {
var next = q.shift();
now - next.interval <= duration && res.push(next.value);
}
o.onNext(res);
o.onCompleted();
});
}, source);
};
var TakeWithTimeObservable = (function (__super__) {
inherits(TakeWithTimeObservable, __super__);
function TakeWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
function scheduleMethod(s, o) {
o.onCompleted();
}
TakeWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(o, this._d, scheduleMethod),
this.source.subscribe(o)
);
};
return TakeWithTimeObservable;
}(ObservableBase));
/**
* Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.takeWithTime(5000, [optional scheduler]);
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
*/
observableProto.takeWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeWithTimeObservable(this, duration, scheduler);
};
var SkipWithTimeObservable = (function (__super__) {
inherits(SkipWithTimeObservable, __super__);
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
__super__.call(this);
}
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
return SkipWithTimeObservable;
}(ObservableBase));
var SkipWithTimeObserver = (function (__super__) {
inherits(SkipWithTimeObserver, __super__);
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
* @description
* Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
* This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
* may not execute immediately, despite the zero due time.
*
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
* @param {Number} duration Duration for skipping elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
*/
observableProto.skipWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipWithTimeObservable(this, duration, scheduler);
};
var SkipUntilWithTimeObservable = (function (__super__) {
inherits(SkipUntilWithTimeObservable, __super__);
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
__super__.call(this);
}
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
return SkipUntilWithTimeObservable;
}(ObservableBase));
var SkipUntilWithTimeObserver = (function (__super__) {
inherits(SkipUntilWithTimeObserver, __super__);
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipUntilWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
*
* @examples
* 1 - res = source.skipUntilWithTime(new Date(), [scheduler]);
* 2 - res = source.skipUntilWithTime(5000, [scheduler]);
* @param {Date|Number} startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped until the specified start time.
*/
observableProto.skipUntilWithTime = function (startTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipUntilWithTimeObservable(this, startTime, scheduler);
};
/**
* Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
* @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
* @param {Scheduler} [scheduler] Scheduler to run the timer on.
* @returns {Observable} An observable sequence with the elements taken until the specified end time.
*/
observableProto.takeUntilWithTime = function (endTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var source = this;
return new AnonymousObservable(function (o) {
return new BinaryDisposable(
scheduler.scheduleFuture(o, endTime, function (_, o) { o.onCompleted(); }),
source.subscribe(o));
}, source);
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
var SwitchFirstObservable = (function (__super__) {
inherits(SwitchFirstObservable, __super__);
function SwitchFirstObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
return SwitchFirstObservable;
}(ObservableBase));
var SwitchFirstObserver = (function(__super__) {
inherits(SwitchFirstObserver, __super__);
function SwitchFirstObserver(state) {
this._s = state;
__super__.call(this);
}
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = observableFromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
inherits(InnerObserver, __super__);
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
return SwitchFirstObserver;
}(AbstractObserver));
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
observableProto.switchFirst = function () {
return new SwitchFirstObservable(this);
};
observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
};
observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
};
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
/** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
Rx.HistoricalScheduler = (function (__super__) {
inherits(HistoricalScheduler, __super__);
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function HistoricalScheduler(initialClock, comparer) {
var clock = initialClock == null ? 0 : initialClock;
var cmp = comparer || defaultSubComparer;
__super__.call(this, clock, cmp);
}
var HistoricalSchedulerProto = HistoricalScheduler.prototype;
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
HistoricalSchedulerProto.add = function (absolute, relative) {
return absolute + relative;
};
HistoricalSchedulerProto.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
* @memberOf HistoricalScheduler
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
HistoricalSchedulerProto.toRelativeTime = function (timeSpan) {
return timeSpan;
};
return HistoricalScheduler;
}(Rx.VirtualTimeScheduler));
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var UnderlyingObservable = (function (__super__) {
inherits(UnderlyingObservable, __super__);
function UnderlyingObservable(m, u) {
this._m = m;
this._u = u;
__super__.call(this);
}
UnderlyingObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._m.getDisposable(), this._u.subscribe(o));
};
return UnderlyingObservable;
}(ObservableBase));
var GroupedObservable = (function (__super__) {
inherits(GroupedObservable, __super__);
function GroupedObservable(key, underlyingObservable, mergedDisposable) {
__super__.call(this);
this.key = key;
this.underlyingObservable = !mergedDisposable ?
underlyingObservable :
new UnderlyingObservable(mergedDisposable, underlyingObservable);
}
GroupedObservable.prototype._subscribe = function (o) {
return this.underlyingObservable.subscribe(o);
};
return GroupedObservable;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: dist/rx.async.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.binding', 'exports'], function (Rx, exports) {
root.Rx = factory(root, exports, Rx);
return root.Rx;
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableFromPromise = Observable.fromPromise,
observableThrow = Observable.throwError,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AsyncSubject = Rx.AsyncSubject,
disposableCreate = Rx.Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
immediateScheduler = Rx.Scheduler.immediate,
defaultScheduler = Rx.Scheduler['default'],
inherits = Rx.internals.inherits,
isScheduler = Rx.Scheduler.isScheduler,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Observable.wrap = function (fn) {
function createObservable() {
return Observable.spawn.call(this, fn.apply(this, arguments));
}
createObservable.__generatorFunction__ = fn;
return createObservable;
};
var spawn = Observable.spawn = function () {
var gen = arguments[0], self = this, args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return new AnonymousObservable(function (o) {
var g = new CompositeDisposable();
if (isFunction(gen)) { gen = gen.apply(self, args); }
if (!gen || !isFunction(gen.next)) {
o.onNext(gen);
return o.onCompleted();
}
function processGenerator(res) {
var ret = tryCatch(gen.next).call(gen, res);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
processGenerator();
function onError(err) {
var ret = tryCatch(gen.next).call(gen, err);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
function next(ret) {
if (ret.done) {
o.onNext(ret.value);
o.onCompleted();
return;
}
var obs = toObservable.call(self, ret.value);
var value = null;
var hasValue = false;
if (Observable.isObservable(obs)) {
g.add(obs.subscribe(function(val) {
hasValue = true;
value = val;
}, onError, function() {
hasValue && processGenerator(value);
}));
} else {
onError(new TypeError('type not supported'));
}
}
return g;
});
};
function toObservable(obj) {
if (!obj) { return obj; }
if (Observable.isObservable(obj)) { return obj; }
if (isPromise(obj)) { return Observable.fromPromise(obj); }
if (isGeneratorFunction(obj) || isGenerator(obj)) { return spawn.call(this, obj); }
if (isFunction(obj)) { return thunkToObservable.call(this, obj); }
if (isArrayLike(obj) || isIterable(obj)) { return arrayToObservable.call(this, obj); }
if (isObject(obj)) {return objectToObservable.call(this, obj);}
return obj;
}
function arrayToObservable (obj) {
return Observable.from(obj).concatMap(function(o) {
if(Observable.isObservable(o) || isObject(o)) {
return toObservable.call(null, o);
} else {
return Rx.Observable.just(o);
}
}).toArray();
}
function objectToObservable (obj) {
var results = new obj.constructor(), keys = Object.keys(obj), observables = [];
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
var observable = toObservable.call(this, obj[key]);
if(observable && Observable.isObservable(observable)) {
defer(observable, key);
} else {
results[key] = obj[key];
}
}
return Observable.forkJoin.apply(Observable, observables).map(function() {
return results;
});
function defer (observable, key) {
results[key] = undefined;
observables.push(observable.map(function (next) {
results[key] = next;
}));
}
}
function thunkToObservable(fn) {
var self = this;
return new AnonymousObservable(function (o) {
fn.call(self, function () {
var err = arguments[0], res = arguments[1];
if (err) { return o.onError(err); }
if (arguments.length > 2) {
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
res = args;
}
o.onNext(res);
o.onCompleted();
});
});
}
function isGenerator(obj) {
return isFunction (obj.next) && isFunction (obj['throw']);
}
function isGeneratorFunction(obj) {
var ctor = obj.constructor;
if (!ctor) { return false; }
if (ctor.name === 'GeneratorFunction' || ctor.displayName === 'GeneratorFunction') { return true; }
return isGenerator(ctor.prototype);
}
function isObject(val) {
return Object == val.constructor;
}
/**
* Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence.
*
* @example
* var res = Rx.Observable.start(function () { console.log('hello'); });
* var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout);
* var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console);
*
* @param {Function} func Function to run asynchronously.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*
* Remarks
* * The function is called immediately, not during the subscription of the resulting sequence.
* * Multiple subscriptions to the resulting sequence can observe the function's result.
*/
Observable.start = function (func, context, scheduler) {
return observableToAsync(func, context, scheduler)();
};
/**
* Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
* @param {Function} function Function to convert to an asynchronous function.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Function} Asynchronous function.
*/
var observableToAsync = Observable.toAsync = function (func, context, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return function () {
var args = arguments,
subject = new AsyncSubject();
scheduler.schedule(null, function () {
var result;
try {
result = func.apply(context, args);
} catch (e) {
subject.onError(e);
return;
}
subject.onNext(result);
subject.onCompleted();
});
return subject.asObservable();
};
};
function createCbObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createCbHandler(o, ctx, selector));
fn.apply(ctx, args);
return o.asObservable();
}
function createCbHandler(o, ctx, selector) {
return function handler () {
var len = arguments.length, results = new Array(len);
for(var i = 0; i < len; i++) { results[i] = arguments[i]; }
if (isFunction(selector)) {
results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) { return o.onError(results.e); }
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
/**
* Converts a callback function to an observable sequence.
*
* @param {Function} fn Function with a callback as the last parameter to convert to an Observable sequence.
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next.
* @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array.
*/
Observable.fromCallback = function (fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length, args = new Array(len)
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return createCbObservable(fn, ctx, selector, args);
};
};
function createNodeObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createNodeHandler(o, ctx, selector));
fn.apply(ctx, args);
return o.asObservable();
}
function createNodeHandler(o, ctx, selector) {
return function handler () {
var err = arguments[0];
if (err) { return o.onError(err); }
var len = arguments.length, results = [];
for(var i = 1; i < len; i++) { results[i - 1] = arguments[i]; }
if (isFunction(selector)) {
var results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) { return o.onError(results.e); }
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
/**
* Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
* @param {Function} fn The function to call
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
* @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
*/
Observable.fromNodeCallback = function (fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return createNodeObservable(fn, ctx, selector, args);
};
};
function isNodeList(el) {
if (root.StaticNodeList) {
// IE8 Specific
// instanceof is slower than Object#toString, but Object#toString will not work as intended in IE8
return el instanceof root.StaticNodeList || el instanceof root.NodeList;
} else {
return Object.prototype.toString.call(el) === '[object NodeList]';
}
}
function ListenDisposable(e, n, fn) {
this._e = e;
this._n = n;
this._fn = fn;
this._e.addEventListener(this._n, this._fn, false);
this.isDisposed = false;
}
ListenDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this._e.removeEventListener(this._n, this._fn, false);
this.isDisposed = true;
}
};
function createEventListener (el, eventName, handler) {
var disposables = new CompositeDisposable();
// Asume NodeList or HTMLCollection
var elemToString = Object.prototype.toString.call(el);
if (isNodeList(el) || elemToString === '[object HTMLCollection]') {
for (var i = 0, len = el.length; i < len; i++) {
disposables.add(createEventListener(el.item(i), eventName, handler));
}
} else if (el) {
disposables.add(new ListenDisposable(el, eventName, handler));
}
return disposables;
}
/**
* Configuration option to determine whether to use native events only
*/
Rx.config.useNativeEvents = false;
var EventObservable = (function(__super__) {
inherits(EventObservable, __super__);
function EventObservable(el, name, fn) {
this._el = el;
this._n = name;
this._fn = fn;
__super__.call(this);
}
function createHandler(o, fn) {
return function handler () {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) { return o.onError(results.e); }
}
o.onNext(results);
};
}
EventObservable.prototype.subscribeCore = function (o) {
return createEventListener(
this._el,
this._n,
createHandler(o, this._fn));
};
return EventObservable;
}(ObservableBase));
/**
* Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList.
* @param {Object} element The DOMElement or NodeList to attach a listener.
* @param {String} eventName The event name to attach the observable sequence.
* @param {Object} eventListenerOptions An object describing EventListenerOptions
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence of events from the specified element and the specified event.
*/
Observable.fromEvent = function (element, eventName, selector, eventListenerOptions) {
// Node.js specific
if (element.addListener) {
return fromEventPattern(
function (h) { element.addListener(eventName, h, eventListenerOptions); },
function (h) { element.removeListener(eventName, h, eventListenerOptions); },
selector);
}
// Use only if non-native events are allowed
if (!Rx.config.useNativeEvents) {
// Handles jq, Angular.js, Zepto, Marionette, Ember.js
if (typeof element.on === 'function' && typeof element.off === 'function') {
return fromEventPattern(
function (h) { element.on(eventName, h, eventListenerOptions); },
function (h) { element.off(eventName, h, eventListenerOptions); },
selector);
}
}
return new EventObservable(element, eventName, selector).publish().refCount();
};
var EventPatternObservable = (function(__super__) {
inherits(EventPatternObservable, __super__);
function EventPatternObservable(add, del, fn) {
this._add = add;
this._del = del;
this._fn = fn;
__super__.call(this);
}
function createHandler(o, fn) {
return function handler () {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) { return o.onError(results.e); }
}
o.onNext(results);
};
}
EventPatternObservable.prototype.subscribeCore = function (o) {
var fn = createHandler(o, this._fn);
var returnValue = this._add(fn);
return new EventPatternDisposable(this._del, fn, returnValue);
};
function EventPatternDisposable(del, fn, ret) {
this._del = del;
this._fn = fn;
this._ret = ret;
this.isDisposed = false;
}
EventPatternDisposable.prototype.dispose = function () {
if(!this.isDisposed) {
isFunction(this._del) && this._del(this._fn, this._ret);
this.isDisposed = true;
}
};
return EventPatternObservable;
}(ObservableBase));
/**
* Creates an observable sequence from an event emitter via an addHandler/removeHandler pair.
* @param {Function} addHandler The function to add a handler to the emitter.
* @param {Function} [removeHandler] The optional function to remove a handler from an emitter.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence which wraps an event from an event emitter
*/
var fromEventPattern = Observable.fromEventPattern = function (addHandler, removeHandler, selector) {
return new EventPatternObservable(addHandler, removeHandler, selector).publish().refCount();
};
/**
* Invokes the asynchronous function, surfacing the result through an observable sequence.
* @param {Function} functionAsync Asynchronous function which returns a Promise to run.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*/
Observable.startAsync = function (functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) { return observableThrow(promise.e); }
return observableFromPromise(promise);
};
return Rx;
}));
================================================
FILE: dist/rx.async.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.binding', 'exports'], function (Rx, exports) {
root.Rx = factory(root, exports, Rx);
return root.Rx;
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableFromPromise = Observable.fromPromise,
observableThrow = Observable.throwError,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AsyncSubject = Rx.AsyncSubject,
disposableCreate = Rx.Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
immediateScheduler = Rx.Scheduler.immediate,
defaultScheduler = Rx.Scheduler['default'],
inherits = Rx.internals.inherits,
isScheduler = Rx.Scheduler.isScheduler,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Observable.wrap = function (fn) {
function createObservable() {
return Observable.spawn.call(this, fn.apply(this, arguments));
}
createObservable.__generatorFunction__ = fn;
return createObservable;
};
var spawn = Observable.spawn = function () {
var gen = arguments[0], self = this, args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return new AnonymousObservable(function (o) {
var g = new CompositeDisposable();
if (isFunction(gen)) { gen = gen.apply(self, args); }
if (!gen || !isFunction(gen.next)) {
o.onNext(gen);
return o.onCompleted();
}
function processGenerator(res) {
var ret = tryCatch(gen.next).call(gen, res);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
processGenerator();
function onError(err) {
var ret = tryCatch(gen.next).call(gen, err);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
function next(ret) {
if (ret.done) {
o.onNext(ret.value);
o.onCompleted();
return;
}
var obs = toObservable.call(self, ret.value);
var value = null;
var hasValue = false;
if (Observable.isObservable(obs)) {
g.add(obs.subscribe(function(val) {
hasValue = true;
value = val;
}, onError, function() {
hasValue && processGenerator(value);
}));
} else {
onError(new TypeError('type not supported'));
}
}
return g;
});
};
function toObservable(obj) {
if (!obj) { return obj; }
if (Observable.isObservable(obj)) { return obj; }
if (isPromise(obj)) { return Observable.fromPromise(obj); }
if (isGeneratorFunction(obj) || isGenerator(obj)) { return spawn.call(this, obj); }
if (isFunction(obj)) { return thunkToObservable.call(this, obj); }
if (isArrayLike(obj) || isIterable(obj)) { return arrayToObservable.call(this, obj); }
if (isObject(obj)) {return objectToObservable.call(this, obj);}
return obj;
}
function arrayToObservable (obj) {
return Observable.from(obj).concatMap(function(o) {
if(Observable.isObservable(o) || isObject(o)) {
return toObservable.call(null, o);
} else {
return Rx.Observable.just(o);
}
}).toArray();
}
function objectToObservable (obj) {
var results = new obj.constructor(), keys = Object.keys(obj), observables = [];
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
var observable = toObservable.call(this, obj[key]);
if(observable && Observable.isObservable(observable)) {
defer(observable, key);
} else {
results[key] = obj[key];
}
}
return Observable.forkJoin.apply(Observable, observables).map(function() {
return results;
});
function defer (observable, key) {
results[key] = undefined;
observables.push(observable.map(function (next) {
results[key] = next;
}));
}
}
function thunkToObservable(fn) {
var self = this;
return new AnonymousObservable(function (o) {
fn.call(self, function () {
var err = arguments[0], res = arguments[1];
if (err) { return o.onError(err); }
if (arguments.length > 2) {
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
res = args;
}
o.onNext(res);
o.onCompleted();
});
});
}
function isGenerator(obj) {
return isFunction (obj.next) && isFunction (obj['throw']);
}
function isGeneratorFunction(obj) {
var ctor = obj.constructor;
if (!ctor) { return false; }
if (ctor.name === 'GeneratorFunction' || ctor.displayName === 'GeneratorFunction') { return true; }
return isGenerator(ctor.prototype);
}
function isObject(val) {
return Object == val.constructor;
}
/**
* Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence.
*
* @example
* var res = Rx.Observable.start(function () { console.log('hello'); });
* var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout);
* var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console);
*
* @param {Function} func Function to run asynchronously.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*
* Remarks
* * The function is called immediately, not during the subscription of the resulting sequence.
* * Multiple subscriptions to the resulting sequence can observe the function's result.
*/
Observable.start = function (func, context, scheduler) {
return observableToAsync(func, context, scheduler)();
};
/**
* Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
* @param {Function} function Function to convert to an asynchronous function.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Function} Asynchronous function.
*/
var observableToAsync = Observable.toAsync = function (func, context, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return function () {
var args = arguments,
subject = new AsyncSubject();
scheduler.schedule(null, function () {
var result;
try {
result = func.apply(context, args);
} catch (e) {
subject.onError(e);
return;
}
subject.onNext(result);
subject.onCompleted();
});
return subject.asObservable();
};
};
function createCbObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createCbHandler(o, ctx, selector));
fn.apply(ctx, args);
return o.asObservable();
}
function createCbHandler(o, ctx, selector) {
return function handler () {
var len = arguments.length, results = new Array(len);
for(var i = 0; i < len; i++) { results[i] = arguments[i]; }
if (isFunction(selector)) {
results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) { return o.onError(results.e); }
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
/**
* Converts a callback function to an observable sequence.
*
* @param {Function} fn Function with a callback as the last parameter to convert to an Observable sequence.
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next.
* @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array.
*/
Observable.fromCallback = function (fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length, args = new Array(len)
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return createCbObservable(fn, ctx, selector, args);
};
};
function createNodeObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createNodeHandler(o, ctx, selector));
fn.apply(ctx, args);
return o.asObservable();
}
function createNodeHandler(o, ctx, selector) {
return function handler () {
var err = arguments[0];
if (err) { return o.onError(err); }
var len = arguments.length, results = [];
for(var i = 1; i < len; i++) { results[i - 1] = arguments[i]; }
if (isFunction(selector)) {
var results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) { return o.onError(results.e); }
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
/**
* Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
* @param {Function} fn The function to call
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
* @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
*/
Observable.fromNodeCallback = function (fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return createNodeObservable(fn, ctx, selector, args);
};
};
function isNodeList(el) {
if (root.StaticNodeList) {
// IE8 Specific
// instanceof is slower than Object#toString, but Object#toString will not work as intended in IE8
return el instanceof root.StaticNodeList || el instanceof root.NodeList;
} else {
return Object.prototype.toString.call(el) === '[object NodeList]';
}
}
function ListenDisposable(e, n, fn) {
this._e = e;
this._n = n;
this._fn = fn;
this._e.addEventListener(this._n, this._fn, false);
this.isDisposed = false;
}
ListenDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this._e.removeEventListener(this._n, this._fn, false);
this.isDisposed = true;
}
};
function createEventListener (el, eventName, handler) {
var disposables = new CompositeDisposable();
// Asume NodeList or HTMLCollection
var elemToString = Object.prototype.toString.call(el);
if (isNodeList(el) || elemToString === '[object HTMLCollection]') {
for (var i = 0, len = el.length; i < len; i++) {
disposables.add(createEventListener(el.item(i), eventName, handler));
}
} else if (el) {
disposables.add(new ListenDisposable(el, eventName, handler));
}
return disposables;
}
/**
* Configuration option to determine whether to use native events only
*/
Rx.config.useNativeEvents = false;
var EventObservable = (function(__super__) {
inherits(EventObservable, __super__);
function EventObservable(el, name, fn) {
this._el = el;
this._n = name;
this._fn = fn;
__super__.call(this);
}
function createHandler(o, fn) {
return function handler () {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) { return o.onError(results.e); }
}
o.onNext(results);
};
}
EventObservable.prototype.subscribeCore = function (o) {
return createEventListener(
this._el,
this._n,
createHandler(o, this._fn));
};
return EventObservable;
}(ObservableBase));
/**
* Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList.
* @param {Object} element The DOMElement or NodeList to attach a listener.
* @param {String} eventName The event name to attach the observable sequence.
* @param {Object} eventListenerOptions An object describing EventListenerOptions
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence of events from the specified element and the specified event.
*/
Observable.fromEvent = function (element, eventName, selector, eventListenerOptions) {
// Node.js specific
if (element.addListener) {
return fromEventPattern(
function (h) { element.addListener(eventName, h, eventListenerOptions); },
function (h) { element.removeListener(eventName, h, eventListenerOptions); },
selector);
}
// Use only if non-native events are allowed
if (!Rx.config.useNativeEvents) {
// Handles jq, Angular.js, Zepto, Marionette, Ember.js
if (typeof element.on === 'function' && typeof element.off === 'function') {
return fromEventPattern(
function (h) { element.on(eventName, h, eventListenerOptions); },
function (h) { element.off(eventName, h, eventListenerOptions); },
selector);
}
}
return new EventObservable(element, eventName, selector).publish().refCount();
};
var EventPatternObservable = (function(__super__) {
inherits(EventPatternObservable, __super__);
function EventPatternObservable(add, del, fn) {
this._add = add;
this._del = del;
this._fn = fn;
__super__.call(this);
}
function createHandler(o, fn) {
return function handler () {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) { return o.onError(results.e); }
}
o.onNext(results);
};
}
EventPatternObservable.prototype.subscribeCore = function (o) {
var fn = createHandler(o, this._fn);
var returnValue = this._add(fn);
return new EventPatternDisposable(this._del, fn, returnValue);
};
function EventPatternDisposable(del, fn, ret) {
this._del = del;
this._fn = fn;
this._ret = ret;
this.isDisposed = false;
}
EventPatternDisposable.prototype.dispose = function () {
if(!this.isDisposed) {
isFunction(this._del) && this._del(this._fn, this._ret);
this.isDisposed = true;
}
};
return EventPatternObservable;
}(ObservableBase));
/**
* Creates an observable sequence from an event emitter via an addHandler/removeHandler pair.
* @param {Function} addHandler The function to add a handler to the emitter.
* @param {Function} [removeHandler] The optional function to remove a handler from an emitter.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence which wraps an event from an event emitter
*/
var fromEventPattern = Observable.fromEventPattern = function (addHandler, removeHandler, selector) {
return new EventPatternObservable(addHandler, removeHandler, selector).publish().refCount();
};
/**
* Invokes the asynchronous function, surfacing the result through an observable sequence.
* @param {Function} functionAsync Asynchronous function which returns a Promise to run.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*/
Observable.startAsync = function (functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) { return observableThrow(promise.e); }
return observableFromPromise(promise);
};
return Rx;
}));
================================================
FILE: dist/rx.backpressure.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
NAryDisposable = Rx.NAryDisposable,
Notification = Rx.Notification,
Subject = Rx.Subject,
Observer = Rx.Observer,
disposableEmpty = Rx.Disposable.empty,
disposableCreate = Rx.Disposable.create,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
defaultScheduler = Rx.Scheduler['default'],
currentThreadScheduler = Rx.Scheduler.currentThread,
identity = Rx.helpers.identity,
isScheduler = Rx.Scheduler.isScheduler,
isFunction = Rx.helpers.isFunction,
checkDisposed = Rx.Disposable.checkDisposed;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
var PausableObservable = (function (__super__) {
inherits(PausableObservable, __super__);
function PausableObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableObservable.prototype._subscribe = function (o) {
var conn = this.source.publish(),
subscription = conn.subscribe(o),
connection = disposableEmpty;
var pausable = this.pauser.startWith(!this.paused).distinctUntilChanged().subscribe(function (b) {
if (b) {
connection = conn.connect();
} else {
connection.dispose();
connection = disposableEmpty;
}
});
return new NAryDisposable([subscription, connection, pausable]);
};
PausableObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausable = function (pauser) {
return new PausableObservable(this, pauser);
};
function combineLatestSource(source, subject, resultSelector) {
return new AnonymousObservable(function (o) {
var hasValue = [false, false],
hasValueAll = false,
isDone = false,
values = new Array(2),
err;
function next(x, i) {
values[i] = x;
hasValue[i] = true;
if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
if (err) { return o.onError(err); }
var res = tryCatch(resultSelector).apply(null, values);
if (res === errorObj) { return o.onError(res.e); }
o.onNext(res);
}
isDone && values[1] && o.onCompleted();
}
return new BinaryDisposable(
source.subscribe(
function (x) {
next(x, 0);
},
function (e) {
if (values[1]) {
o.onError(e);
} else {
err = e;
}
},
function () {
isDone = true;
values[1] && o.onCompleted();
}),
subject.subscribe(
function (x) {
next(x, 1);
},
function (e) { o.onError(e); },
function () {
isDone = true;
next(true, 1);
})
);
}, source);
}
var PausableBufferedObservable = (function (__super__) {
inherits(PausableBufferedObservable, __super__);
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableBufferedObservable.prototype._subscribe = function (o) {
var q = [], previousShouldFire;
function drainQueue() { while (q.length > 0) { o.onNext(q.shift()); } }
var subscription =
combineLatestSource(
this.source,
this.pauser.startWith(!this.paused).distinctUntilChanged(),
function (data, shouldFire) {
return { data: data, shouldFire: shouldFire };
})
.subscribe(
function (results) {
if (previousShouldFire !== undefined && results.shouldFire !== previousShouldFire) {
previousShouldFire = results.shouldFire;
// change in shouldFire
if (results.shouldFire) { drainQueue(); }
} else {
previousShouldFire = results.shouldFire;
// new data
if (results.shouldFire) {
o.onNext(results.data);
} else {
q.push(results.data);
}
}
},
function (err) {
drainQueue();
o.onError(err);
},
function () {
drainQueue();
o.onCompleted();
}
);
return subscription;
};
PausableBufferedObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableBufferedObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableBufferedObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausableBuffered = function (pauser) {
return new PausableBufferedObservable(this, pauser);
};
var ControlledObservable = (function (__super__) {
inherits(ControlledObservable, __super__);
function ControlledObservable (source, enableQueue, scheduler) {
__super__.call(this);
this.subject = new ControlledSubject(enableQueue, scheduler);
this.source = source.multicast(this.subject).refCount();
}
ControlledObservable.prototype._subscribe = function (o) {
return this.source.subscribe(o);
};
ControlledObservable.prototype.request = function (numberOfItems) {
return this.subject.request(numberOfItems == null ? -1 : numberOfItems);
};
return ControlledObservable;
}(Observable));
var ControlledSubject = (function (__super__) {
inherits(ControlledSubject, __super__);
function ControlledSubject(enableQueue, scheduler) {
enableQueue == null && (enableQueue = true);
__super__.call(this);
this.subject = new Subject();
this.enableQueue = enableQueue;
this.queue = enableQueue ? [] : null;
this.requestedCount = 0;
this.requestedDisposable = null;
this.error = null;
this.hasFailed = false;
this.hasCompleted = false;
this.scheduler = scheduler || currentThreadScheduler;
}
addProperties(ControlledSubject.prototype, Observer, {
_subscribe: function (o) {
return this.subject.subscribe(o);
},
onCompleted: function () {
this.hasCompleted = true;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onCompleted();
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnCompleted());
}
},
onError: function (error) {
this.hasFailed = true;
this.error = error;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onError(error);
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnError(error));
}
},
onNext: function (value) {
if (this.requestedCount <= 0) {
this.enableQueue && this.queue.push(Notification.createOnNext(value));
} else {
(this.requestedCount-- === 0) && this.disposeCurrentRequest();
this.subject.onNext(value);
}
},
_processRequest: function (numberOfItems) {
if (this.enableQueue) {
while (this.queue.length > 0 && (numberOfItems > 0 || this.queue[0].kind !== 'N')) {
var first = this.queue.shift();
first.accept(this.subject);
if (first.kind === 'N') {
numberOfItems--;
} else {
this.disposeCurrentRequest();
this.queue = [];
}
}
}
return numberOfItems;
},
request: function (number) {
this.disposeCurrentRequest();
var self = this;
this.requestedDisposable = this.scheduler.schedule(number,
function(s, i) {
var remaining = self._processRequest(i);
var stopped = self.hasCompleted || self.hasFailed;
if (!stopped && remaining > 0) {
self.requestedCount = remaining;
return disposableCreate(function () {
self.requestedCount = 0;
});
// Scheduled item is still in progress. Return a new
// disposable to allow the request to be interrupted
// via dispose.
}
});
return this.requestedDisposable;
},
disposeCurrentRequest: function () {
if (this.requestedDisposable) {
this.requestedDisposable.dispose();
this.requestedDisposable = null;
}
}
});
return ControlledSubject;
}(Observable));
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
observableProto.controlled = function (enableQueue, scheduler) {
if (enableQueue && isScheduler(enableQueue)) {
scheduler = enableQueue;
enableQueue = true;
}
if (enableQueue == null) { enableQueue = true; }
return new ControlledObservable(this, enableQueue, scheduler);
};
var StopAndWaitObservable = (function (__super__) {
inherits(StopAndWaitObservable, __super__);
function StopAndWaitObservable (source) {
__super__.call(this);
this.source = source;
}
function scheduleMethod(s, self) {
return self.source.request(1);
}
StopAndWaitObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new StopAndWaitObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var StopAndWaitObserver = (function (__sub__) {
inherits(StopAndWaitObserver, __sub__);
function StopAndWaitObserver (observer, observable, cancel) {
__sub__.call(this);
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.scheduleDisposable = null;
}
StopAndWaitObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
StopAndWaitObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(1);
}
StopAndWaitObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod);
};
StopAndWaitObserver.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return StopAndWaitObserver;
}(AbstractObserver));
return StopAndWaitObservable;
}(Observable));
/**
* Attaches a stop and wait observable to the current observable.
* @returns {Observable} A stop and wait observable.
*/
ControlledObservable.prototype.stopAndWait = function () {
return new StopAndWaitObservable(this);
};
var WindowedObservable = (function (__super__) {
inherits(WindowedObservable, __super__);
function WindowedObservable(source, windowSize) {
__super__.call(this);
this.source = source;
this.windowSize = windowSize;
}
function scheduleMethod(s, self) {
return self.source.request(self.windowSize);
}
WindowedObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new WindowedObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var WindowedObserver = (function (__sub__) {
inherits(WindowedObserver, __sub__);
function WindowedObserver(observer, observable, cancel) {
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.received = 0;
this.scheduleDisposable = null;
__sub__.call(this);
}
WindowedObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
WindowedObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(self.observable.windowSize);
}
WindowedObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.received = ++this.received % this.observable.windowSize;
this.received === 0 && (this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod));
};
WindowedObserver.prototype.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return WindowedObserver;
}(AbstractObserver));
return WindowedObservable;
}(Observable));
/**
* Creates a sliding windowed observable based upon the window size.
* @param {Number} windowSize The number of items in the window
* @returns {Observable} A windowed observable based upon the window size.
*/
ControlledObservable.prototype.windowed = function (windowSize) {
return new WindowedObservable(this, windowSize);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
return Rx;
}));
================================================
FILE: dist/rx.binding.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
Subject = Rx.Subject,
AsyncSubject = Rx.AsyncSubject,
Observer = Rx.Observer,
ScheduledObserver = Rx.internals.ScheduledObserver,
disposableCreate = Rx.Disposable.create,
disposableEmpty = Rx.Disposable.empty,
BinaryDisposable = Rx.BinaryDisposable,
currentThreadScheduler = Rx.Scheduler.currentThread,
isFunction = Rx.helpers.isFunction,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
checkDisposed = Rx.Disposable.checkDisposed;
// Utilities
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var MulticastObservable = (function (__super__) {
inherits(MulticastObservable, __super__);
function MulticastObservable(source, fn1, fn2) {
this.source = source;
this._fn1 = fn1;
this._fn2 = fn2;
__super__.call(this);
}
MulticastObservable.prototype.subscribeCore = function (o) {
var connectable = this.source.multicast(this._fn1());
return new BinaryDisposable(this._fn2(connectable).subscribe(o), connectable.connect());
};
return MulticastObservable;
}(ObservableBase));
/**
* Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
* subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
* invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
*
* @example
* 1 - res = source.multicast(observable);
* 2 - res = source.multicast(function () { return new Subject(); }, function (x) { return x; });
*
* @param {Function|Subject} subjectOrSubjectSelector
* Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
* Or:
* Subject to push source elements into.
*
* @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
var RefCountObservable = (function (__super__) {
inherits(RefCountObservable, __super__);
function RefCountObservable(source) {
this.source = source;
this._count = 0;
this._connectableSubscription = null;
__super__.call(this);
}
RefCountObservable.prototype.subscribeCore = function (o) {
var subscription = this.source.subscribe(o);
++this._count === 1 && (this._connectableSubscription = this.source.connect());
return new RefCountDisposable(this, subscription);
};
function RefCountDisposable(p, s) {
this._p = p;
this._s = s;
this.isDisposed = false;
}
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.dispose();
--this._p._count === 0 && this._p._connectableSubscription.dispose();
}
};
return RefCountObservable;
}(ObservableBase));
var ConnectableObservable = Rx.ConnectableObservable = (function (__super__) {
inherits(ConnectableObservable, __super__);
function ConnectableObservable(source, subject) {
this.source = source;
this._connection = null;
this._source = source.asObservable();
this._subject = subject;
__super__.call(this);
}
function ConnectDisposable(parent, subscription) {
this._p = parent;
this._s = subscription;
}
ConnectDisposable.prototype.dispose = function () {
if (this._s) {
this._s.dispose();
this._s = null;
this._p._connection = null;
}
};
ConnectableObservable.prototype.connect = function () {
if (!this._connection) {
if (this._subject.isStopped) {
return disposableEmpty;
}
var subscription = this._source.subscribe(this._subject);
this._connection = new ConnectDisposable(this, subscription);
}
return this._connection;
};
ConnectableObservable.prototype._subscribe = function (o) {
return this._subject.subscribe(o);
};
ConnectableObservable.prototype.refCount = function () {
return new RefCountObservable(this);
};
return ConnectableObservable;
}(Observable));
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence
* can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`)
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source.
*/
observableProto.singleInstance = function() {
var source = this, hasObservable = false, observable;
function getObservable() {
if (!hasObservable) {
hasObservable = true;
observable = source['finally'](function() { hasObservable = false; }).publish().refCount();
}
return observable;
}
return new AnonymousObservable(function(o) {
return getObservable().subscribe(o);
});
};
return Rx;
}));
================================================
FILE: dist/rx.coincidence.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
var Observable = Rx.Observable,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
Subject = Rx.Subject,
observableProto = Observable.prototype,
observableEmpty = Observable.empty,
observableNever = Observable.never,
AnonymousObservable = Rx.AnonymousObservable,
addRef = Rx.internals.addRef,
inherits = Rx.internals.inherits,
bindCallback = Rx.internals.bindCallback,
noop = Rx.helpers.noop,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* Correlates the elements of two sequences based on overlapping durations.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences. The parameters passed to the function correspond with the elements from the left and right source sequences for which overlap occurs.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.join = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var leftDone = false, rightDone = false;
var leftId = 0, rightId = 0;
var leftMap = new Map(), rightMap = new Map();
var handleError = function (e) { o.onError(e); };
group.add(left.subscribe(
function (value) {
var id = leftId++, md = new SingleAssignmentDisposable();
leftMap.set(id, value);
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
leftMap['delete'](id) && leftMap.size === 0 && leftDone && o.onCompleted();
group.remove(md);
}));
rightMap.forEach(function (v) {
var result = tryCatch(resultSelector)(value, v);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
leftDone = true;
(rightDone || leftMap.size === 0) && o.onCompleted();
})
);
group.add(right.subscribe(
function (value) {
var id = rightId++, md = new SingleAssignmentDisposable();
rightMap.set(id, value);
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
rightMap['delete'](id) && rightMap.size === 0 && rightDone && o.onCompleted();
group.remove(md);
}));
leftMap.forEach(function (v) {
var result = tryCatch(resultSelector)(v, value);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
rightDone = true;
(leftDone || rightMap.size === 0) && o.onCompleted();
})
);
return group;
}, left);
};
/**
* Correlates the elements of two sequences based on overlapping durations, and groups the results.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence. The first parameter passed to the function is an element of the left sequence. The second parameter passed to the function is an observable sequence with elements from the right sequence that overlap with the left sequence's element.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.groupJoin = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var r = new RefCountDisposable(group);
var leftMap = new Map(), rightMap = new Map();
var leftId = 0, rightId = 0;
var handleError = function (e) { return function (v) { v.onError(e); }; };
function handleError(e) { };
group.add(left.subscribe(
function (value) {
var s = new Subject();
var id = leftId++;
leftMap.set(id, s);
var result = tryCatch(resultSelector)(value, addRef(s, r));
if (result === errorObj) {
leftMap.forEach(handleError(result.e));
return o.onError(result.e);
}
o.onNext(result);
rightMap.forEach(function (v) { s.onNext(v); });
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () {
leftMap['delete'](id) && s.onCompleted();
group.remove(md);
}));
},
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () { o.onCompleted(); })
);
group.add(right.subscribe(
function (value) {
var id = rightId++;
rightMap.set(id, value);
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () {
rightMap['delete'](id);
group.remove(md);
}));
leftMap.forEach(function (v) { v.onNext(value); });
},
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
})
);
return r;
}, left);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers.
* @param {Mixed} bufferOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [bufferClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.buffer = function () {
return this.window.apply(this, arguments)
.flatMap(toArray);
};
/**
* Projects each element of an observable sequence into zero or more windows.
*
* @param {Mixed} windowOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [windowClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.window = function (windowOpeningsOrClosingSelector, windowClosingSelector) {
if (arguments.length === 1 && typeof arguments[0] !== 'function') {
return observableWindowWithBoundaries.call(this, windowOpeningsOrClosingSelector);
}
return typeof windowOpeningsOrClosingSelector === 'function' ?
observableWindowWithClosingSelector.call(this, windowOpeningsOrClosingSelector) :
observableWindowWithOpenings.call(this, windowOpeningsOrClosingSelector, windowClosingSelector);
};
function observableWindowWithOpenings(windowOpenings, windowClosingSelector) {
return windowOpenings.groupJoin(this, windowClosingSelector, observableEmpty, function (_, win) {
return win;
});
}
function observableWindowWithBoundaries(windowBoundaries) {
var source = this;
return new AnonymousObservable(function (observer) {
var win = new Subject(),
d = new CompositeDisposable(),
r = new RefCountDisposable(d);
observer.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
isPromise(windowBoundaries) && (windowBoundaries = observableFromPromise(windowBoundaries));
d.add(windowBoundaries.subscribe(function (w) {
win.onCompleted();
win = new Subject();
observer.onNext(addRef(win, r));
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
return r;
}, source);
}
function observableWindowWithClosingSelector(windowClosingSelector) {
var source = this;
return new AnonymousObservable(function (observer) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
r = new RefCountDisposable(d),
win = new Subject();
observer.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
function createWindowClose () {
var windowClose;
try {
windowClose = windowClosingSelector();
} catch (e) {
observer.onError(e);
return;
}
isPromise(windowClose) && (windowClose = observableFromPromise(windowClose));
var m1 = new SingleAssignmentDisposable();
m.setDisposable(m1);
m1.setDisposable(windowClose.take(1).subscribe(noop, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
win = new Subject();
observer.onNext(addRef(win, r));
createWindowClose();
}));
}
createWindowClose();
return r;
}, source);
}
var PairwiseObservable = (function (__super__) {
inherits(PairwiseObservable, __super__);
function PairwiseObservable(source) {
this.source = source;
__super__.call(this);
}
PairwiseObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new PairwiseObserver(o));
};
return PairwiseObservable;
}(ObservableBase));
var PairwiseObserver = (function(__super__) {
inherits(PairwiseObserver, __super__);
function PairwiseObserver(o) {
this._o = o;
this._p = null;
this._hp = false;
__super__.call(this);
}
PairwiseObserver.prototype.next = function (x) {
if (this._hp) {
this._o.onNext([this._p, x]);
} else {
this._hp = true;
}
this._p = x;
};
PairwiseObserver.prototype.error = function (err) { this._o.onError(err); };
PairwiseObserver.prototype.completed = function () { this._o.onCompleted(); };
return PairwiseObserver;
}(AbstractObserver));
/**
* Returns a new observable that triggers on the second and subsequent triggerings of the input observable.
* The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair.
* The argument passed to the N-1th triggering is held in hidden internal state until the Nth triggering occurs.
* @returns {Observable} An observable that triggers on successive pairs of observations from the input observable as an array.
*/
observableProto.pairwise = function () {
return new PairwiseObservable(this);
};
/**
* Returns two observables which partition the observations of the source by the given function.
* The first will trigger observations for those values for which the predicate returns true.
* The second will trigger observations for those values where the predicate returns false.
* The predicate is executed once for each subscribed observer.
* Both also propagate all error observations arising from the source and each completes
* when the source completes.
* @param {Function} predicate
* The function to determine which output Observable will trigger a particular observation.
* @returns {Array}
* An array of observables. The first triggers when the predicate returns true,
* and the second triggers when the predicate returns false.
*/
observableProto.partition = function(predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return [
this.filter(predicate, thisArg),
this.filter(function (x, i, o) { return !fn(x, i, o); })
];
};
/**
* Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
*
* @example
* var res = observable.groupBy(function (x) { return x.id; });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} [elementSelector] A function to map each source element to an element in an observable group.
* @returns {Observable} A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
*/
observableProto.groupBy = function (keySelector, elementSelector) {
return this.groupByUntil(keySelector, elementSelector, observableNever);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function.
* A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
* key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
*
* @example
* var res = observable.groupByUntil(function (x) { return x.id; }, null, function () { return Rx.Observable.never(); });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} durationSelector A function to signal the expiration of a group.
* @returns {Observable}
* A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
* If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
*
*/
observableProto.groupByUntil = function (keySelector, elementSelector, durationSelector) {
var source = this;
return new AnonymousObservable(function (o) {
var map = new Map(),
groupDisposable = new CompositeDisposable(),
refCountDisposable = new RefCountDisposable(groupDisposable),
handleError = function (e) { return function (item) { item.onError(e); }; };
groupDisposable.add(
source.subscribe(function (x) {
var key = tryCatch(keySelector)(x);
if (key === errorObj) {
map.forEach(handleError(key.e));
return o.onError(key.e);
}
var fireNewMapEntry = false, writer = map.get(key);
if (writer === undefined) {
writer = new Subject();
map.set(key, writer);
fireNewMapEntry = true;
}
if (fireNewMapEntry) {
var group = new GroupedObservable(key, writer, refCountDisposable),
durationGroup = new GroupedObservable(key, writer);
var duration = tryCatch(durationSelector)(durationGroup);
if (duration === errorObj) {
map.forEach(handleError(duration.e));
return o.onError(duration.e);
}
o.onNext(group);
var md = new SingleAssignmentDisposable();
groupDisposable.add(md);
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
map.forEach(handleError(e));
o.onError(e);
},
function () {
if (map['delete'](key)) { writer.onCompleted(); }
groupDisposable.remove(md);
}));
}
var element = x;
if (isFunction(elementSelector)) {
element = tryCatch(elementSelector)(x);
if (element === errorObj) {
map.forEach(handleError(element.e));
return o.onError(element.e);
}
}
writer.onNext(element);
}, function (e) {
map.forEach(handleError(e));
o.onError(e);
}, function () {
map.forEach(function (item) { item.onCompleted(); });
o.onCompleted();
}));
return refCountDisposable;
}, source);
};
var UnderlyingObservable = (function (__super__) {
inherits(UnderlyingObservable, __super__);
function UnderlyingObservable(m, u) {
this._m = m;
this._u = u;
__super__.call(this);
}
UnderlyingObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._m.getDisposable(), this._u.subscribe(o));
};
return UnderlyingObservable;
}(ObservableBase));
var GroupedObservable = (function (__super__) {
inherits(GroupedObservable, __super__);
function GroupedObservable(key, underlyingObservable, mergedDisposable) {
__super__.call(this);
this.key = key;
this.underlyingObservable = !mergedDisposable ?
underlyingObservable :
new UnderlyingObservable(mergedDisposable, underlyingObservable);
}
GroupedObservable.prototype._subscribe = function (o) {
return this.underlyingObservable.subscribe(o);
};
return GroupedObservable;
}(Observable));
return Rx;
}));
================================================
FILE: dist/rx.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
// Utilities
var toString = Object.prototype.toString;
var arrayClass = '[object Array]',
funcClass = '[object Function]',
stringClass = '[object String]';
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k++;
}
};
}
var boxedString = Object('a'),
splitString = boxedString[0] !== 'a' || !(0 in boxedString);
if (!Array.prototype.every) {
Array.prototype.every = function every(fun /*, thisp */) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self && !fun.call(thisp, self[i], i, object)) {
return false;
}
}
return true;
};
}
if (!Array.prototype.map) {
Array.prototype.map = function map(fun /*, thisp*/) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
result = new Array(length),
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self) {
result[i] = fun.call(thisp, self[i], i, object);
}
}
return result;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function (predicate) {
var results = [], item, t = new Object(this);
for (var i = 0, len = t.length >>> 0; i < len; i++) {
item = t[i];
if (i in t && predicate.call(arguments[1], item, i, t)) {
results.push(item);
}
}
return results;
};
}
if (!Array.isArray) {
Array.isArray = function (arg) {
return toString.call(arg) === arrayClass;
};
}
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(searchElement) {
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== Infinity && n !== -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
// Fix for Tessel
if (!Object.prototype.propertyIsEnumerable) {
Object.prototype.propertyIsEnumerable = function (key) {
for (var k in this) { if (k === key) { return true; } }
return false;
};
}
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
if (typeof Object.create !== 'function') {
// Production steps of ECMA-262, Edition 5, 15.2.3.5
// Reference: http://es5.github.io/#x15.2.3.5
Object.create = (function() {
function Temp() {}
var hasOwn = Object.prototype.hasOwnProperty;
return function (O) {
if (typeof O !== 'object') {
throw new TypeError('Object prototype may only be an Object or null');
}
Temp.prototype = O;
var obj = new Temp();
Temp.prototype = null;
if (arguments.length > 1) {
// Object.defineProperties does ToObject on its first argument.
var Properties = Object(arguments[1]);
for (var prop in Properties) {
if (hasOwn.call(Properties, prop)) {
obj[prop] = Properties[prop];
}
}
}
// 5. Return obj
return obj;
};
})();
}
root.Element && root.Element.prototype.attachEvent && !root.Element.prototype.addEventListener && (function () {
function addMethod(name, fn) {
Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = fn;
}
addMethod('addEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
target.attachEvent('on' + type, typeListeners.event = function (e) {
e || (e = root.event);
var documentElement = target.document &&
target.document.documentElement ||
target.documentElement ||
{ scrollLeft: 0, scrollTop: 0 };
e.currentTarget = target;
e.pageX = e.clientX + documentElement.scrollLeft;
e.pageY = e.clientY + documentElement.scrollTop;
e.preventDefault = function () {
e.bubbledKeyCode = e.keyCode;
if (e.ctrlKey) {
try {
e.keyCode = 0;
} catch (e) { }
}
e.defaultPrevented = true;
e.returnValue = false;
e.modified = true;
e.returnValue = false;
};
e.stopImmediatePropagation = function () {
immediatePropagation = false;
e.cancelBubble = true;
};
e.stopPropagation = function () {
e.cancelBubble = true;
};
e.relatedTarget = e.fromElement || null;
e.target = e.srcElement || target;
e.timeStamp = +new Date();
// Normalize key events
switch(e.type) {
case 'keypress':
var c = ('charCode' in e ? e.charCode : e.keyCode);
if (c === 10) {
c = 0;
e.keyCode = 13;
} else if (c === 13 || c === 27) {
c = 0;
} else if (c === 3) {
c = 99;
}
e.charCode = c;
e.keyChar = e.charCode ? String.fromCharCode(e.charCode) : '';
break;
}
var copiedEvent = {};
for (var prop in e) {
copiedEvent[prop] = e[prop];
}
for (var i = 0, typeListenersCache = [].concat(typeListeners), typeListenerCache, immediatePropagation = true; immediatePropagation && (typeListenerCache = typeListenersCache[i]); ++i) {
for (var ii = 0, typeListener; typeListener = typeListeners[ii]; ++ii) {
if (typeListener === typeListenerCache) { typeListener.call(target, copiedEvent); break; }
}
}
});
typeListeners.push(listener);
});
addMethod('removeEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
for (var i = typeListeners.length - 1, typeListener; typeListener = typeListeners[i]; --i) {
if (typeListener === listener) { typeListeners.splice(i, 1); break; }
}
!typeListeners.length &&
typeListeners.event &&
target.detachEvent('on' + type, typeListeners.event);
});
addMethod('dispatchEvent', function (e) {
var target = this;
var type = e.type;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
try {
return target.fireEvent('on' + type, e);
} catch (err) {
return typeListeners.event && typeListeners.event(e);
}
});
function ready() {
if (ready.interval && document.body) {
ready.interval = clearInterval(ready.interval);
document.dispatchEvent(new CustomEvent('DOMContentLoaded'));
}
}
ready.interval = setInterval(ready, 1);
root.addEventListener('load', ready);
}());
(!root.CustomEvent || typeof root.CustomEvent === 'object') && (function() {
function CustomEvent (type, params) {
var event;
params = params || { bubbles: false, cancelable: false, detail: undefined };
try {
if (document.createEvent) {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
} else if (document.createEventObject) {
event = document.createEventObject();
}
} catch (error) {
event = document.createEvent('Event');
event.initEvent(type, params.bubbles, params.cancelable);
event.detail = params.detail;
}
return event;
}
root.CustomEvent && (CustomEvent.prototype = root.CustomEvent.prototype);
root.CustomEvent = CustomEvent;
}());
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
schedulerProto.catchError = schedulerProto['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
var CatchScheduler = (function (__super__) {
inherits(CatchScheduler, __super__);
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
__super__.call(this);
}
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () { return this._scheduler.now(); };
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) { thrower(res.e); }
return disposableEmpty;
}
return disposableFixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this, failed = false, d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) { return null; }
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) { thrower(res.e); }
d.dispose();
return null;
}
return res;
}));
return d;
};
return CatchScheduler;
}(Scheduler));
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var self = this;
return new AnonymousObserver(
function (x) { self.onNext(x); },
function (err) { self.onError(err); },
function () { self.onCompleted(); });
};
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var cb = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return cb(notificationCreateOnNext(x));
}, function (e) {
return cb(notificationCreateOnError(e));
}, function () {
return cb(notificationCreateOnCompleted());
});
};
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.prototype.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
Observer.prototype.makeSafe = function(disposable) {
return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var FromPromiseObservable = (function(__super__) {
inherits(FromPromiseObservable, __super__);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
__super__.call(this);
}
function scheduleNext(s, state) {
var o = state[0], data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0], err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function(o) {
var sad = new SingleAssignmentDisposable(), self = this, p = this._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p
.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
return FromPromiseObservable;
}(ObservableBase));
/**
* Converts a Promise to an Observable sequence
* @param {Promise} An ES6 Compliant promise.
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
var observableFromPromise = Observable.fromPromise = function (promise, scheduler) {
scheduler || (scheduler = defaultScheduler);
return new FromPromiseObservable(promise, scheduler);
};
/*
* Converts an existing observable sequence to an ES6 Compatible Promise
* @example
* var promise = Rx.Observable.return(42).toPromise(RSVP.Promise);
*
* // With config
* Rx.config.Promise = RSVP.Promise;
* var promise = Rx.Observable.return(42).toPromise();
* @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise.
* @returns {Promise} An ES6 compatible promise with the last value from the observable sequence.
*/
observableProto.toPromise = function (promiseCtor) {
promiseCtor || (promiseCtor = Rx.config.Promise);
if (!promiseCtor) { throw new NotSupportedError('Promise type not provided nor in Rx.config.Promise'); }
var source = this;
return new promiseCtor(function (resolve, reject) {
// No cancellation can be done
var value;
source.subscribe(function (v) {
value = v;
}, reject, function () {
resolve(value);
});
});
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
/**
* Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.concatMapObserver = observableProto.selectConcatObserver = function(onNext, onError, onCompleted, thisArg) {
var source = this,
onNextFunc = bindCallback(onNext, thisArg, 2),
onErrorFunc = bindCallback(onError, thisArg, 1),
onCompletedFunc = bindCallback(onCompleted, thisArg, 0);
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNextFunc(x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onErrorFunc(err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompletedFunc();
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, this).concatAll();
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
/**
* Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.flatMapObserver = observableProto.selectManyObserver = function (onNext, onError, onCompleted, thisArg) {
var source = this;
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNext.call(thisArg, x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onError.call(thisArg, err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompleted.call(thisArg);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, source).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
var RefCountObservable = (function (__super__) {
inherits(RefCountObservable, __super__);
function RefCountObservable(source) {
this.source = source;
this._count = 0;
this._connectableSubscription = null;
__super__.call(this);
}
RefCountObservable.prototype.subscribeCore = function (o) {
var subscription = this.source.subscribe(o);
++this._count === 1 && (this._connectableSubscription = this.source.connect());
return new RefCountDisposable(this, subscription);
};
function RefCountDisposable(p, s) {
this._p = p;
this._s = s;
this.isDisposed = false;
}
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.dispose();
--this._p._count === 0 && this._p._connectableSubscription.dispose();
}
};
return RefCountObservable;
}(ObservableBase));
var ConnectableObservable = Rx.ConnectableObservable = (function (__super__) {
inherits(ConnectableObservable, __super__);
function ConnectableObservable(source, subject) {
this.source = source;
this._connection = null;
this._source = source.asObservable();
this._subject = subject;
__super__.call(this);
}
function ConnectDisposable(parent, subscription) {
this._p = parent;
this._s = subscription;
}
ConnectDisposable.prototype.dispose = function () {
if (this._s) {
this._s.dispose();
this._s = null;
this._p._connection = null;
}
};
ConnectableObservable.prototype.connect = function () {
if (!this._connection) {
if (this._subject.isStopped) {
return disposableEmpty;
}
var subscription = this._source.subscribe(this._subject);
this._connection = new ConnectDisposable(this, subscription);
}
return this._connection;
};
ConnectableObservable.prototype._subscribe = function (o) {
return this._subject.subscribe(o);
};
ConnectableObservable.prototype.refCount = function () {
return new RefCountObservable(this);
};
return ConnectableObservable;
}(Observable));
return Rx;
}));
================================================
FILE: dist/rx.core.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var
noop = Rx.helpers.noop = function () { },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && !isFunction(p.subscribe) && isFunction(p.then); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); }
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Error.prototype;
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Error.prototype;
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: dist/rx.core.testing.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.core'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx.core'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
notImplemented = Rx.helpers.notImplemented,
defaultComparer = Rx.helpers.defaultComparer = function (a, b) { return isEqual(a, b); };
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
return Rx;
}));
================================================
FILE: dist/rx.experimental.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
FlatMapObservable = Rx.FlatMapObservable,
observableConcat = Observable.concat,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
disposableEmpty = Rx.Disposable.empty,
CompositeDisposable = Rx.CompositeDisposable,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Enumerable = Rx.internals.Enumerable,
enumerableOf = Enumerable.of,
currentThreadScheduler = Rx.Scheduler.currentThread,
AsyncSubject = Rx.AsyncSubject,
Observer = Rx.Observer,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
helpers = Rx.helpers,
noop = helpers.noop,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var WhileEnumerable = (function(__super__) {
inherits(WhileEnumerable, __super__);
function WhileEnumerable(c, s) {
this.c = c;
this.s = s;
}
WhileEnumerable.prototype[$iterator$] = function () {
var self = this;
return {
next: function () {
return self.c() ?
{ done: false, value: self.s } :
{ done: true, value: void 0 };
}
};
};
return WhileEnumerable;
}(Enumerable));
function enumerableWhile(condition, source) {
return new WhileEnumerable(condition, source);
}
/**
* Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions.
* This operator allows for a fluent style of writing queries that use the same sequence multiple times.
*
* @param {Function} selector Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
observableProto.letBind = observableProto['let'] = function (func) {
return func(this);
};
/**
* Determines whether an observable collection contains values.
*
* @example
* 1 - res = Rx.Observable.if(condition, obs1);
* 2 - res = Rx.Observable.if(condition, obs1, obs2);
* 3 - res = Rx.Observable.if(condition, obs1, scheduler);
* @param {Function} condition The condition which determines if the thenSource or elseSource will be run.
* @param {Observable} thenSource The observable sequence or Promise that will be run if the condition function returns true.
* @param {Observable} [elseSource] The observable sequence or Promise that will be run if the condition function returns false. If this is not provided, it defaults to Rx.Observabe.Empty with the specified scheduler.
* @returns {Observable} An observable sequence which is either the thenSource or elseSource.
*/
Observable['if'] = function (condition, thenSource, elseSourceOrScheduler) {
return observableDefer(function () {
elseSourceOrScheduler || (elseSourceOrScheduler = observableEmpty());
isPromise(thenSource) && (thenSource = observableFromPromise(thenSource));
isPromise(elseSourceOrScheduler) && (elseSourceOrScheduler = observableFromPromise(elseSourceOrScheduler));
// Assume a scheduler for empty only
typeof elseSourceOrScheduler.now === 'function' && (elseSourceOrScheduler = observableEmpty(elseSourceOrScheduler));
return condition() ? thenSource : elseSourceOrScheduler;
});
};
/**
* Concatenates the observable sequences obtained by running the specified result selector for each element in source.
* There is an alias for this method called 'forIn' for browsers 0) {
work = state.q.shift();
} else {
state.isAcquired = false;
return;
}
var m1 = new SingleAssignmentDisposable();
state.d.add(m1);
m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
recurse([state, self]);
}
ExpandObservable.prototype._ensureActive = function (state) {
var isOwner = false;
if (state.q.length > 0) {
isOwner = !state.isAcquired;
state.isAcquired = true;
}
isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
};
ExpandObservable.prototype.subscribeCore = function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
state = {
q: [],
m: m,
d: d,
activeCount: 0,
isAcquired: false,
o: o
};
state.q.push(this.source);
state.activeCount++;
this._ensureActive(state);
return d;
};
return ExpandObservable;
}(ObservableBase));
var ExpandObserver = (function(__super__) {
inherits(ExpandObserver, __super__);
function ExpandObserver(state, parent, m1) {
this._s = state;
this._p = parent;
this._m1 = m1;
__super__.call(this);
}
ExpandObserver.prototype.next = function (x) {
this._s.o.onNext(x);
var result = tryCatch(this._p._fn)(x);
if (result === errorObj) { return this._s.o.onError(result.e); }
this._s.q.push(result);
this._s.activeCount++;
this._p._ensureActive(this._s);
};
ExpandObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ExpandObserver.prototype.completed = function () {
this._s.d.remove(this._m1);
this._s.activeCount--;
this._s.activeCount === 0 && this._s.o.onCompleted();
};
return ExpandObserver;
}(AbstractObserver));
/**
* Expands an observable sequence by recursively invoking selector.
*
* @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
* @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
* @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
*/
observableProto.expand = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new ExpandObservable(this, selector, scheduler);
};
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ForkJoinObservable = (function (__super__) {
inherits(ForkJoinObservable, __super__);
function ForkJoinObservable(sources, cb) {
this._sources = sources;
this._cb = cb;
__super__.call(this);
}
ForkJoinObservable.prototype.subscribeCore = function (o) {
if (this._sources.length === 0) {
o.onCompleted();
return disposableEmpty;
}
var count = this._sources.length;
var state = {
finished: false,
hasResults: new Array(count),
hasCompleted: new Array(count),
results: new Array(count)
};
var subscriptions = new CompositeDisposable();
for (var i = 0, len = this._sources.length; i < len; i++) {
var source = this._sources[i];
isPromise(source) && (source = observableFromPromise(source));
subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
}
return subscriptions;
};
return ForkJoinObservable;
}(ObservableBase));
var ForkJoinObserver = (function(__super__) {
inherits(ForkJoinObserver, __super__);
function ForkJoinObserver(o, s, i, cb, subs) {
this._o = o;
this._s = s;
this._i = i;
this._cb = cb;
this._subs = subs;
__super__.call(this);
}
ForkJoinObserver.prototype.next = function (x) {
if (!this._s.finished) {
this._s.hasResults[this._i] = true;
this._s.results[this._i] = x;
}
};
ForkJoinObserver.prototype.error = function (e) {
this._s.finished = true;
this._o.onError(e);
this._subs.dispose();
};
ForkJoinObserver.prototype.completed = function () {
if (!this._s.finished) {
if (!this._s.hasResults[this._i]) {
return this._o.onCompleted();
}
this._s.hasCompleted[this._i] = true;
for (var i = 0; i < this._s.results.length; i++) {
if (!this._s.hasCompleted[i]) { return; }
}
this._s.finished = true;
var res = tryCatch(this._cb).apply(null, this._s.results);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
this._o.onCompleted();
}
};
return ForkJoinObserver;
}(AbstractObserver));
/**
* Runs all observable sequences in parallel and collect their last elements.
*
* @example
* 1 - res = Rx.Observable.forkJoin([obs1, obs2]);
* 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...);
* @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences.
*/
Observable.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new ForkJoinObservable(args, resultSelector);
};
/**
* Runs two observable sequences in parallel and combines their last elemenets.
* @param {Observable} second Second observable sequence.
* @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences.
* @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences.
*/
observableProto.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return Observable.forkJoin.apply(null, args);
};
/**
* Comonadic bind operator.
* @param {Function} selector A transform function to apply to each element.
* @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
* @returns {Observable} An observable sequence which results from the comonadic bind operation.
*/
observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
var source = this;
return observableDefer(function () {
var chain;
return source
.map(function (x) {
var curr = new ChainObservable(x);
chain && chain.onNext(x);
chain = curr;
return curr;
})
.tap(
noop,
function (e) { chain && chain.onError(e); },
function () { chain && chain.onCompleted(); }
)
.observeOn(scheduler)
.map(selector);
}, source);
};
var ChainObservable = (function (__super__) {
inherits(ChainObservable, __super__);
function ChainObservable(head) {
__super__.call(this);
this.head = head;
this.tail = new AsyncSubject();
}
addProperties(ChainObservable.prototype, Observer, {
_subscribe: function (o) {
var g = new CompositeDisposable();
g.add(currentThreadScheduler.schedule(this, function (_, self) {
o.onNext(self.head);
g.add(self.tail.mergeAll().subscribe(o));
}));
return g;
},
onCompleted: function () {
this.onNext(Observable.empty());
},
onError: function (e) {
this.onNext(Observable['throw'](e));
},
onNext: function (v) {
this.tail.onNext(v);
this.tail.onCompleted();
}
});
return ChainObservable;
}(Observable));
var SwitchFirstObservable = (function (__super__) {
inherits(SwitchFirstObservable, __super__);
function SwitchFirstObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
return SwitchFirstObservable;
}(ObservableBase));
var SwitchFirstObserver = (function(__super__) {
inherits(SwitchFirstObserver, __super__);
function SwitchFirstObserver(state) {
this._s = state;
__super__.call(this);
}
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = observableFromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
inherits(InnerObserver, __super__);
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
return SwitchFirstObserver;
}(AbstractObserver));
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
observableProto.switchFirst = function () {
return new SwitchFirstObservable(this);
};
observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
};
observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
};
return Rx;
}));
================================================
FILE: dist/rx.joinpatterns.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
observableThrow = Observable.throwError,
observerCreate = Rx.Observer.create,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
AbstractObserver = Rx.internals.AbstractObserver,
noop = Rx.helpers.noop,
inherits = Rx.internals.inherits,
isFunction = Rx.helpers.isFunction;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this.patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this.patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
function Plan(expression, selector) {
this.expression = expression;
this.selector = selector;
}
function handleOnError(o) { return function (e) { o.onError(e); }; }
function handleOnNext(self, observer) {
return function onNext () {
var result = tryCatch(self.selector).apply(self, arguments);
if (result === errorObj) { return observer.onError(result.e); }
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [], errHandler = handleOnError(observer);
for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this.joinObserverArray = joinObserverArray;
this.onNext = onNext;
this.onCompleted = onCompleted;
this.joinObservers = new Map();
for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
var joinObserver = this.joinObserverArray[i];
this.joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this.joinObservers.forEach(function (v) { v.queue.shift(); });
};
ActivePlan.prototype.match = function () {
var i, len, hasValues = true;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
if (this.joinObserverArray[i].queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
firstValues.push(this.joinObserverArray[i].queue[0]);
this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this.onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this.onNext.apply(this, values);
}
}
};
var JoinObserver = (function (__super__) {
inherits(JoinObserver, __super__);
function JoinObserver(source, onError) {
__super__.call(this);
this.source = source;
this.onError = onError;
this.queue = [];
this.activePlans = [];
this.subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
var JoinObserverPrototype = JoinObserver.prototype;
JoinObserverPrototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this.onError(notification.error);
}
this.queue.push(notification);
var activePlans = this.activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserverPrototype.error = noop;
JoinObserverPrototype.completed = noop;
JoinObserverPrototype.addActivePlan = function (activePlan) {
this.activePlans.push(activePlan);
};
JoinObserverPrototype.subscribe = function () {
this.subscription.setDisposable(this.source.materialize().subscribe(this));
};
JoinObserverPrototype.removeActivePlan = function (activePlan) {
this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
this.activePlans.length === 0 && this.dispose();
};
JoinObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this.subscription.dispose();
}
};
return JoinObserver;
} (AbstractObserver));
/**
* Creates a pattern that matches when both observable sequences have an available value.
*
* @param right Observable sequence to match with the current sequence.
* @return {Pattern} Pattern object that matches when both observable sequences have an available value.
*/
observableProto.and = function (right) {
return new Pattern([this, right]);
};
/**
* Matches when the observable sequence has an available value and projects the value.
*
* @param {Function} selector Selector that will be invoked for values in the source sequence.
* @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
observableProto.thenDo = function (selector) {
return new Pattern([this]).thenDo(selector);
};
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
Observable.when = function () {
var len = arguments.length, plans;
if (Array.isArray(arguments[0])) {
plans = arguments[0];
} else {
plans = new Array(len);
for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
}
return new AnonymousObservable(function (o) {
var activePlans = [],
externalSubscriptions = new Map();
var outObserver = observerCreate(
function (x) { o.onNext(x); },
function (err) {
externalSubscriptions.forEach(function (v) { v.onError(err); });
o.onError(err);
},
function (x) { o.onCompleted(); }
);
try {
for (var i = 0, len = plans.length; i < len; i++) {
activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return observableThrow(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
});
};
return Rx;
}));
================================================
FILE: dist/rx.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) { for(var a = [], i = 0, len = arr.length; i < len; i++) { a.push(arr[i]); } return a;}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
schedulerProto.catchError = schedulerProto['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
var CatchScheduler = (function (__super__) {
inherits(CatchScheduler, __super__);
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
__super__.call(this);
}
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () { return this._scheduler.now(); };
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) { thrower(res.e); }
return disposableEmpty;
}
return disposableFixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this, failed = false, d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) { return null; }
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) { thrower(res.e); }
d.dispose();
return null;
}
return res;
}));
return d;
};
return CatchScheduler;
}(Scheduler));
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var self = this;
return new AnonymousObserver(
function (x) { self.onNext(x); },
function (err) { self.onError(err); },
function () { self.onCompleted(); });
};
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var cb = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return cb(notificationCreateOnNext(x));
}, function (e) {
return cb(notificationCreateOnError(e));
}, function () {
return cb(notificationCreateOnCompleted());
});
};
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.prototype.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
Observer.prototype.makeSafe = function(disposable) {
return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var FromPromiseObservable = (function(__super__) {
inherits(FromPromiseObservable, __super__);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
__super__.call(this);
}
function scheduleNext(s, state) {
var o = state[0], data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0], err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function(o) {
var sad = new SingleAssignmentDisposable(), self = this, p = this._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p
.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
return FromPromiseObservable;
}(ObservableBase));
/**
* Converts a Promise to an Observable sequence
* @param {Promise} An ES6 Compliant promise.
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
var observableFromPromise = Observable.fromPromise = function (promise, scheduler) {
scheduler || (scheduler = defaultScheduler);
return new FromPromiseObservable(promise, scheduler);
};
/*
* Converts an existing observable sequence to an ES6 Compatible Promise
* @example
* var promise = Rx.Observable.return(42).toPromise(RSVP.Promise);
*
* // With config
* Rx.config.Promise = RSVP.Promise;
* var promise = Rx.Observable.return(42).toPromise();
* @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise.
* @returns {Promise} An ES6 compatible promise with the last value from the observable sequence.
*/
observableProto.toPromise = function (promiseCtor) {
promiseCtor || (promiseCtor = Rx.config.Promise);
if (!promiseCtor) { throw new NotSupportedError('Promise type not provided nor in Rx.config.Promise'); }
var source = this;
return new promiseCtor(function (resolve, reject) {
// No cancellation can be done
var value;
source.subscribe(function (v) {
value = v;
}, reject, function () {
resolve(value);
});
});
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
/**
* Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.concatMapObserver = observableProto.selectConcatObserver = function(onNext, onError, onCompleted, thisArg) {
var source = this,
onNextFunc = bindCallback(onNext, thisArg, 2),
onErrorFunc = bindCallback(onError, thisArg, 1),
onCompletedFunc = bindCallback(onCompleted, thisArg, 0);
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNextFunc(x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onErrorFunc(err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompletedFunc();
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, this).concatAll();
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
/**
* Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.flatMapObserver = observableProto.selectManyObserver = function (onNext, onError, onCompleted, thisArg) {
var source = this;
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNext.call(thisArg, x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onError.call(thisArg, err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompleted.call(thisArg);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, source).mergeAll();
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
var PausableObservable = (function (__super__) {
inherits(PausableObservable, __super__);
function PausableObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableObservable.prototype._subscribe = function (o) {
var conn = this.source.publish(),
subscription = conn.subscribe(o),
connection = disposableEmpty;
var pausable = this.pauser.startWith(!this.paused).distinctUntilChanged().subscribe(function (b) {
if (b) {
connection = conn.connect();
} else {
connection.dispose();
connection = disposableEmpty;
}
});
return new NAryDisposable([subscription, connection, pausable]);
};
PausableObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausable = function (pauser) {
return new PausableObservable(this, pauser);
};
function combineLatestSource(source, subject, resultSelector) {
return new AnonymousObservable(function (o) {
var hasValue = [false, false],
hasValueAll = false,
isDone = false,
values = new Array(2),
err;
function next(x, i) {
values[i] = x;
hasValue[i] = true;
if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
if (err) { return o.onError(err); }
var res = tryCatch(resultSelector).apply(null, values);
if (res === errorObj) { return o.onError(res.e); }
o.onNext(res);
}
isDone && values[1] && o.onCompleted();
}
return new BinaryDisposable(
source.subscribe(
function (x) {
next(x, 0);
},
function (e) {
if (values[1]) {
o.onError(e);
} else {
err = e;
}
},
function () {
isDone = true;
values[1] && o.onCompleted();
}),
subject.subscribe(
function (x) {
next(x, 1);
},
function (e) { o.onError(e); },
function () {
isDone = true;
next(true, 1);
})
);
}, source);
}
var PausableBufferedObservable = (function (__super__) {
inherits(PausableBufferedObservable, __super__);
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableBufferedObservable.prototype._subscribe = function (o) {
var q = [], previousShouldFire;
function drainQueue() { while (q.length > 0) { o.onNext(q.shift()); } }
var subscription =
combineLatestSource(
this.source,
this.pauser.startWith(!this.paused).distinctUntilChanged(),
function (data, shouldFire) {
return { data: data, shouldFire: shouldFire };
})
.subscribe(
function (results) {
if (previousShouldFire !== undefined && results.shouldFire !== previousShouldFire) {
previousShouldFire = results.shouldFire;
// change in shouldFire
if (results.shouldFire) { drainQueue(); }
} else {
previousShouldFire = results.shouldFire;
// new data
if (results.shouldFire) {
o.onNext(results.data);
} else {
q.push(results.data);
}
}
},
function (err) {
drainQueue();
o.onError(err);
},
function () {
drainQueue();
o.onCompleted();
}
);
return subscription;
};
PausableBufferedObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableBufferedObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableBufferedObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausableBuffered = function (pauser) {
return new PausableBufferedObservable(this, pauser);
};
var ControlledObservable = (function (__super__) {
inherits(ControlledObservable, __super__);
function ControlledObservable (source, enableQueue, scheduler) {
__super__.call(this);
this.subject = new ControlledSubject(enableQueue, scheduler);
this.source = source.multicast(this.subject).refCount();
}
ControlledObservable.prototype._subscribe = function (o) {
return this.source.subscribe(o);
};
ControlledObservable.prototype.request = function (numberOfItems) {
return this.subject.request(numberOfItems == null ? -1 : numberOfItems);
};
return ControlledObservable;
}(Observable));
var ControlledSubject = (function (__super__) {
inherits(ControlledSubject, __super__);
function ControlledSubject(enableQueue, scheduler) {
enableQueue == null && (enableQueue = true);
__super__.call(this);
this.subject = new Subject();
this.enableQueue = enableQueue;
this.queue = enableQueue ? [] : null;
this.requestedCount = 0;
this.requestedDisposable = null;
this.error = null;
this.hasFailed = false;
this.hasCompleted = false;
this.scheduler = scheduler || currentThreadScheduler;
}
addProperties(ControlledSubject.prototype, Observer, {
_subscribe: function (o) {
return this.subject.subscribe(o);
},
onCompleted: function () {
this.hasCompleted = true;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onCompleted();
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnCompleted());
}
},
onError: function (error) {
this.hasFailed = true;
this.error = error;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onError(error);
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnError(error));
}
},
onNext: function (value) {
if (this.requestedCount <= 0) {
this.enableQueue && this.queue.push(Notification.createOnNext(value));
} else {
(this.requestedCount-- === 0) && this.disposeCurrentRequest();
this.subject.onNext(value);
}
},
_processRequest: function (numberOfItems) {
if (this.enableQueue) {
while (this.queue.length > 0 && (numberOfItems > 0 || this.queue[0].kind !== 'N')) {
var first = this.queue.shift();
first.accept(this.subject);
if (first.kind === 'N') {
numberOfItems--;
} else {
this.disposeCurrentRequest();
this.queue = [];
}
}
}
return numberOfItems;
},
request: function (number) {
this.disposeCurrentRequest();
var self = this;
this.requestedDisposable = this.scheduler.schedule(number,
function(s, i) {
var remaining = self._processRequest(i);
var stopped = self.hasCompleted || self.hasFailed;
if (!stopped && remaining > 0) {
self.requestedCount = remaining;
return disposableCreate(function () {
self.requestedCount = 0;
});
// Scheduled item is still in progress. Return a new
// disposable to allow the request to be interrupted
// via dispose.
}
});
return this.requestedDisposable;
},
disposeCurrentRequest: function () {
if (this.requestedDisposable) {
this.requestedDisposable.dispose();
this.requestedDisposable = null;
}
}
});
return ControlledSubject;
}(Observable));
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
observableProto.controlled = function (enableQueue, scheduler) {
if (enableQueue && isScheduler(enableQueue)) {
scheduler = enableQueue;
enableQueue = true;
}
if (enableQueue == null) { enableQueue = true; }
return new ControlledObservable(this, enableQueue, scheduler);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: dist/rx.lite.extras.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
observableNever = Observable.never,
observableThrow = Observable['throw'],
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AnonymousObserver = Rx.AnonymousObserver,
notificationCreateOnNext = Rx.Notification.createOnNext,
notificationCreateOnError = Rx.Notification.createOnError,
notificationCreateOnCompleted = Rx.Notification.createOnCompleted,
Observer = Rx.Observer,
observerCreate = Observer.create,
AbstractObserver = Rx.internals.AbstractObserver,
Subject = Rx.Subject,
internals = Rx.internals,
helpers = Rx.helpers,
ScheduledObserver = internals.ScheduledObserver,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
disposableEmpty = Rx.Disposable.empty,
immediateScheduler = Rx.Scheduler.immediate,
defaultKeySerializer = helpers.defaultKeySerializer,
addRef = Rx.internals.addRef,
identity = helpers.identity,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
inherits = internals.inherits,
bindCallback = internals.bindCallback,
noop = helpers.noop,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
*
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var handlerFunc = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return handlerFunc(notificationCreateOnNext(x));
}, function (e) {
return handlerFunc(notificationCreateOnError(e));
}, function () {
return handlerFunc(notificationCreateOnCompleted());
});
};
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var source = this;
return new AnonymousObserver(
function (x) { source.onNext(x); },
function (e) { source.onError(e); },
function () { source.onCompleted(); }
);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var UsingObservable = (function (__super__) {
inherits(UsingObservable, __super__);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
__super__.call(this);
}
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = disposableEmpty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(observableThrow(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(observableThrow(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
return UsingObservable;
}(ObservableBase));
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
Observable.using = function (resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
/**
* Propagates the observable sequence or Promise that reacts first.
* @param {Observable} rightSource Second observable sequence or Promise.
* @returns {Observable} {Observable} An observable sequence that surfaces either of the given sequences, whichever reacted first.
*/
observableProto.amb = function (rightSource) {
var leftSource = this;
return new AnonymousObservable(function (observer) {
var choice,
leftChoice = 'L', rightChoice = 'R',
leftSubscription = new SingleAssignmentDisposable(),
rightSubscription = new SingleAssignmentDisposable();
isPromise(rightSource) && (rightSource = observableFromPromise(rightSource));
function choiceL() {
if (!choice) {
choice = leftChoice;
rightSubscription.dispose();
}
}
function choiceR() {
if (!choice) {
choice = rightChoice;
leftSubscription.dispose();
}
}
var leftSubscribe = observerCreate(
function (left) {
choiceL();
choice === leftChoice && observer.onNext(left);
},
function (e) {
choiceL();
choice === leftChoice && observer.onError(e);
},
function () {
choiceL();
choice === leftChoice && observer.onCompleted();
}
);
var rightSubscribe = observerCreate(
function (right) {
choiceR();
choice === rightChoice && observer.onNext(right);
},
function (e) {
choiceR();
choice === rightChoice && observer.onError(e);
},
function () {
choiceR();
choice === rightChoice && observer.onCompleted();
}
);
leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));
rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));
return new BinaryDisposable(leftSubscription, rightSubscription);
});
};
function amb(p, c) { return p.amb(c); }
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
Observable.amb = function () {
var acc = observableNever(), items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(items);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
for (var i = 0, len = items.length; i < len; i++) {
acc = amb(acc, items[i]);
}
return acc;
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence
* can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`)
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source.
*/
observableProto.singleInstance = function() {
var source = this, hasObservable = false, observable;
function getObservable() {
if (!hasObservable) {
hasObservable = true;
observable = source['finally'](function() { hasObservable = false; }).publish().refCount();
}
return observable;
}
return new AnonymousObservable(function(o) {
return getObservable().subscribe(o);
});
};
return Rx;
}));
================================================
FILE: dist/rx.lite.extras.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
observableNever = Observable.never,
observableThrow = Observable['throw'],
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AnonymousObserver = Rx.AnonymousObserver,
notificationCreateOnNext = Rx.Notification.createOnNext,
notificationCreateOnError = Rx.Notification.createOnError,
notificationCreateOnCompleted = Rx.Notification.createOnCompleted,
Observer = Rx.Observer,
observerCreate = Observer.create,
AbstractObserver = Rx.internals.AbstractObserver,
Subject = Rx.Subject,
internals = Rx.internals,
helpers = Rx.helpers,
ScheduledObserver = internals.ScheduledObserver,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
disposableEmpty = Rx.Disposable.empty,
immediateScheduler = Rx.Scheduler.immediate,
defaultKeySerializer = helpers.defaultKeySerializer,
addRef = Rx.internals.addRef,
identity = helpers.identity,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
inherits = internals.inherits,
bindCallback = internals.bindCallback,
noop = helpers.noop,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
*
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var handlerFunc = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return handlerFunc(notificationCreateOnNext(x));
}, function (e) {
return handlerFunc(notificationCreateOnError(e));
}, function () {
return handlerFunc(notificationCreateOnCompleted());
});
};
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var source = this;
return new AnonymousObserver(
function (x) { source.onNext(x); },
function (e) { source.onError(e); },
function () { source.onCompleted(); }
);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var UsingObservable = (function (__super__) {
inherits(UsingObservable, __super__);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
__super__.call(this);
}
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = disposableEmpty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(observableThrow(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(observableThrow(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
return UsingObservable;
}(ObservableBase));
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
Observable.using = function (resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
/**
* Propagates the observable sequence or Promise that reacts first.
* @param {Observable} rightSource Second observable sequence or Promise.
* @returns {Observable} {Observable} An observable sequence that surfaces either of the given sequences, whichever reacted first.
*/
observableProto.amb = function (rightSource) {
var leftSource = this;
return new AnonymousObservable(function (observer) {
var choice,
leftChoice = 'L', rightChoice = 'R',
leftSubscription = new SingleAssignmentDisposable(),
rightSubscription = new SingleAssignmentDisposable();
isPromise(rightSource) && (rightSource = observableFromPromise(rightSource));
function choiceL() {
if (!choice) {
choice = leftChoice;
rightSubscription.dispose();
}
}
function choiceR() {
if (!choice) {
choice = rightChoice;
leftSubscription.dispose();
}
}
var leftSubscribe = observerCreate(
function (left) {
choiceL();
choice === leftChoice && observer.onNext(left);
},
function (e) {
choiceL();
choice === leftChoice && observer.onError(e);
},
function () {
choiceL();
choice === leftChoice && observer.onCompleted();
}
);
var rightSubscribe = observerCreate(
function (right) {
choiceR();
choice === rightChoice && observer.onNext(right);
},
function (e) {
choiceR();
choice === rightChoice && observer.onError(e);
},
function () {
choiceR();
choice === rightChoice && observer.onCompleted();
}
);
leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));
rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));
return new BinaryDisposable(leftSubscription, rightSubscription);
});
};
function amb(p, c) { return p.amb(c); }
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
Observable.amb = function () {
var acc = observableNever(), items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(items);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
for (var i = 0, len = items.length; i < len; i++) {
acc = amb(acc, items[i]);
}
return acc;
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence
* can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`)
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source.
*/
observableProto.singleInstance = function() {
var source = this, hasObservable = false, observable;
function getObservable() {
if (!hasObservable) {
hasObservable = true;
observable = source['finally'](function() { hasObservable = false; }).publish().refCount();
}
return observable;
}
return new AnonymousObservable(function(o) {
return getObservable().subscribe(o);
});
};
return Rx;
}));
================================================
FILE: dist/rx.lite.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
var PausableObservable = (function (__super__) {
inherits(PausableObservable, __super__);
function PausableObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableObservable.prototype._subscribe = function (o) {
var conn = this.source.publish(),
subscription = conn.subscribe(o),
connection = disposableEmpty;
var pausable = this.pauser.startWith(!this.paused).distinctUntilChanged().subscribe(function (b) {
if (b) {
connection = conn.connect();
} else {
connection.dispose();
connection = disposableEmpty;
}
});
return new NAryDisposable([subscription, connection, pausable]);
};
PausableObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausable = function (pauser) {
return new PausableObservable(this, pauser);
};
function combineLatestSource(source, subject, resultSelector) {
return new AnonymousObservable(function (o) {
var hasValue = [false, false],
hasValueAll = false,
isDone = false,
values = new Array(2),
err;
function next(x, i) {
values[i] = x;
hasValue[i] = true;
if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
if (err) { return o.onError(err); }
var res = tryCatch(resultSelector).apply(null, values);
if (res === errorObj) { return o.onError(res.e); }
o.onNext(res);
}
isDone && values[1] && o.onCompleted();
}
return new BinaryDisposable(
source.subscribe(
function (x) {
next(x, 0);
},
function (e) {
if (values[1]) {
o.onError(e);
} else {
err = e;
}
},
function () {
isDone = true;
values[1] && o.onCompleted();
}),
subject.subscribe(
function (x) {
next(x, 1);
},
function (e) { o.onError(e); },
function () {
isDone = true;
next(true, 1);
})
);
}, source);
}
var PausableBufferedObservable = (function (__super__) {
inherits(PausableBufferedObservable, __super__);
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableBufferedObservable.prototype._subscribe = function (o) {
var q = [], previousShouldFire;
function drainQueue() { while (q.length > 0) { o.onNext(q.shift()); } }
var subscription =
combineLatestSource(
this.source,
this.pauser.startWith(!this.paused).distinctUntilChanged(),
function (data, shouldFire) {
return { data: data, shouldFire: shouldFire };
})
.subscribe(
function (results) {
if (previousShouldFire !== undefined && results.shouldFire !== previousShouldFire) {
previousShouldFire = results.shouldFire;
// change in shouldFire
if (results.shouldFire) { drainQueue(); }
} else {
previousShouldFire = results.shouldFire;
// new data
if (results.shouldFire) {
o.onNext(results.data);
} else {
q.push(results.data);
}
}
},
function (err) {
drainQueue();
o.onError(err);
},
function () {
drainQueue();
o.onCompleted();
}
);
return subscription;
};
PausableBufferedObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableBufferedObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableBufferedObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausableBuffered = function (pauser) {
return new PausableBufferedObservable(this, pauser);
};
var ControlledObservable = (function (__super__) {
inherits(ControlledObservable, __super__);
function ControlledObservable (source, enableQueue, scheduler) {
__super__.call(this);
this.subject = new ControlledSubject(enableQueue, scheduler);
this.source = source.multicast(this.subject).refCount();
}
ControlledObservable.prototype._subscribe = function (o) {
return this.source.subscribe(o);
};
ControlledObservable.prototype.request = function (numberOfItems) {
return this.subject.request(numberOfItems == null ? -1 : numberOfItems);
};
return ControlledObservable;
}(Observable));
var ControlledSubject = (function (__super__) {
inherits(ControlledSubject, __super__);
function ControlledSubject(enableQueue, scheduler) {
enableQueue == null && (enableQueue = true);
__super__.call(this);
this.subject = new Subject();
this.enableQueue = enableQueue;
this.queue = enableQueue ? [] : null;
this.requestedCount = 0;
this.requestedDisposable = null;
this.error = null;
this.hasFailed = false;
this.hasCompleted = false;
this.scheduler = scheduler || currentThreadScheduler;
}
addProperties(ControlledSubject.prototype, Observer, {
_subscribe: function (o) {
return this.subject.subscribe(o);
},
onCompleted: function () {
this.hasCompleted = true;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onCompleted();
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnCompleted());
}
},
onError: function (error) {
this.hasFailed = true;
this.error = error;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onError(error);
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnError(error));
}
},
onNext: function (value) {
if (this.requestedCount <= 0) {
this.enableQueue && this.queue.push(Notification.createOnNext(value));
} else {
(this.requestedCount-- === 0) && this.disposeCurrentRequest();
this.subject.onNext(value);
}
},
_processRequest: function (numberOfItems) {
if (this.enableQueue) {
while (this.queue.length > 0 && (numberOfItems > 0 || this.queue[0].kind !== 'N')) {
var first = this.queue.shift();
first.accept(this.subject);
if (first.kind === 'N') {
numberOfItems--;
} else {
this.disposeCurrentRequest();
this.queue = [];
}
}
}
return numberOfItems;
},
request: function (number) {
this.disposeCurrentRequest();
var self = this;
this.requestedDisposable = this.scheduler.schedule(number,
function(s, i) {
var remaining = self._processRequest(i);
var stopped = self.hasCompleted || self.hasFailed;
if (!stopped && remaining > 0) {
self.requestedCount = remaining;
return disposableCreate(function () {
self.requestedCount = 0;
});
// Scheduled item is still in progress. Return a new
// disposable to allow the request to be interrupted
// via dispose.
}
});
return this.requestedDisposable;
},
disposeCurrentRequest: function () {
if (this.requestedDisposable) {
this.requestedDisposable.dispose();
this.requestedDisposable = null;
}
}
});
return ControlledSubject;
}(Observable));
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
observableProto.controlled = function (enableQueue, scheduler) {
if (enableQueue && isScheduler(enableQueue)) {
scheduler = enableQueue;
enableQueue = true;
}
if (enableQueue == null) { enableQueue = true; }
return new ControlledObservable(this, enableQueue, scheduler);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: dist/rx.sorting.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
observableNever = Observable.never,
isEqual = Rx.internals.isEqual,
defaultSubComparer = Rx.helpers.defaultSubComparer;
/**
* jortSort checks if your inputs are sorted. Note that this is only for a sequence with an end.
* See http://jort.technology/ for full details.
* @returns {Observable} An observable which has a single value of true if sorted, else false.
*/
observableProto.jortSort = function () {
return this.jortSortUntil(observableNever());
};
/**
* jortSort checks if your inputs are sorted until another Observable sequence fires.
* See http://jort.technology/ for full details.
* @returns {Observable} An observable which has a single value of true if sorted, else false.
*/
observableProto.jortSortUntil = function (other) {
var source = this;
return new AnonymousObservable(function (observer) {
var arr = [];
return source.takeUntil(other).subscribe(
arr.push.bind(arr),
observer.onError.bind(observer),
function () {
var sorted = arr.slice(0).sort(defaultSubComparer);
observer.onNext(isEqual(arr, sorted));
observer.onCompleted();
});
}, source);
};
return Rx;
}));
================================================
FILE: dist/rx.testing.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.virtualtime', 'exports'], function (Rx, exports) {
root.Rx = factory(root, exports, Rx);
return root.Rx;
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Notification = Rx.Notification,
VirtualTimeScheduler = Rx.VirtualTimeScheduler,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
inherits = Rx.internals.inherits,
defaultComparer = Rx.internals.isEqual;
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
return Rx;
}));
================================================
FILE: dist/rx.time.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Refernces
var inherits = Rx.internals.inherits,
AbstractObserver = Rx.internals.AbstractObserver,
Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
observableNever = Observable.never,
observableThrow = Observable['throw'],
observableFromArray = Observable.fromArray,
defaultScheduler = Rx.Scheduler['default'],
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
Subject = Rx.Subject,
addRef = Rx.internals.addRef,
normalizeTime = Rx.Scheduler.normalize,
helpers = Rx.helpers,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var TimerObservable = (function(__super__) {
inherits(TimerObservable, __super__);
function TimerObservable(dt, s) {
this._dt = dt;
this._s = s;
__super__.call(this);
}
TimerObservable.prototype.subscribeCore = function (o) {
return this._s.scheduleFuture(o, this._dt, scheduleMethod);
};
function scheduleMethod(s, o) {
o.onNext(0);
o.onCompleted();
}
return TimerObservable;
}(ObservableBase));
function _observableTimer(dueTime, scheduler) {
return new TimerObservable(dueTime, scheduler);
}
function observableTimerDateAndPeriod(dueTime, period, scheduler) {
return new AnonymousObservable(function (observer) {
var d = dueTime, p = normalizeTime(period);
return scheduler.scheduleRecursiveFuture(0, d, function (count, self) {
if (p > 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
* @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTime = observableProto.windowTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
var source = this, timeShift;
timeShiftOrScheduler == null && (timeShift = timeSpan);
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (typeof timeShiftOrScheduler === 'number') {
timeShift = timeShiftOrScheduler;
} else if (isScheduler(timeShiftOrScheduler)) {
timeShift = timeSpan;
scheduler = timeShiftOrScheduler;
}
return new AnonymousObservable(function (observer) {
var groupDisposable,
nextShift = timeShift,
nextSpan = timeSpan,
q = [],
refCountDisposable,
timerD = new SerialDisposable(),
totalTime = 0;
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable);
function createTimer () {
var m = new SingleAssignmentDisposable(),
isSpan = false,
isShift = false;
timerD.setDisposable(m);
if (nextSpan === nextShift) {
isSpan = true;
isShift = true;
} else if (nextSpan < nextShift) {
isSpan = true;
} else {
isShift = true;
}
var newTotalTime = isSpan ? nextSpan : nextShift,
ts = newTotalTime - totalTime;
totalTime = newTotalTime;
if (isSpan) {
nextSpan += timeShift;
}
if (isShift) {
nextShift += timeShift;
}
m.setDisposable(scheduler.scheduleFuture(null, ts, function () {
if (isShift) {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
isSpan && q.shift().onCompleted();
createTimer();
}));
};
q.push(new Subject());
observer.onNext(addRef(q[0], refCountDisposable));
createTimer();
groupDisposable.add(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
},
function (e) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onError(e); }
observer.onError(e);
},
function () {
for (var i = 0, len = q.length; i < len; i++) { q[i].onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
/**
* Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a window.
* @param {Number} count Maximum element count of a window.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTimeOrCount = observableProto.windowTimeOrCount = function (timeSpan, count, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (observer) {
var timerD = new SerialDisposable(),
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable),
n = 0,
windowId = 0,
s = new Subject();
function createTimer(id) {
var m = new SingleAssignmentDisposable();
timerD.setDisposable(m);
m.setDisposable(scheduler.scheduleFuture(null, timeSpan, function () {
if (id !== windowId) { return; }
n = 0;
var newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
createTimer(newId);
}));
}
observer.onNext(addRef(s, refCountDisposable));
createTimer(0);
groupDisposable.add(source.subscribe(
function (x) {
var newId = 0, newWindow = false;
s.onNext(x);
if (++n === count) {
newWindow = true;
n = 0;
newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
}
newWindow && createTimer(newId);
},
function (e) {
s.onError(e);
observer.onError(e);
}, function () {
s.onCompleted();
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
* @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
* @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTime = observableProto.bufferTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
return this.windowWithTime(timeSpan, timeShiftOrScheduler, scheduler).flatMap(toArray);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a buffer.
* @param {Number} count Maximum element count of a buffer.
* @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTimeOrCount = observableProto.bufferTimeOrCount = function (timeSpan, count, scheduler) {
return this.windowWithTimeOrCount(timeSpan, count, scheduler).flatMap(toArray);
};
var TimeIntervalObservable = (function (__super__) {
inherits(TimeIntervalObservable, __super__);
function TimeIntervalObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimeIntervalObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimeIntervalObserver(o, this._s));
};
return TimeIntervalObservable;
}(ObservableBase));
var TimeIntervalObserver = (function (__super__) {
inherits(TimeIntervalObserver, __super__);
function TimeIntervalObserver(o, s) {
this._o = o;
this._s = s;
this._l = s.now();
__super__.call(this);
}
TimeIntervalObserver.prototype.next = function (x) {
var now = this._s.now(), span = now - this._l;
this._l = now;
this._o.onNext({ value: x, interval: span });
};
TimeIntervalObserver.prototype.error = function (e) { this._o.onError(e); };
TimeIntervalObserver.prototype.completed = function () { this._o.onCompleted(); };
return TimeIntervalObserver;
}(AbstractObserver));
/**
* Records the time interval between consecutive values in an observable sequence.
*
* @example
* 1 - res = source.timeInterval();
* 2 - res = source.timeInterval(Rx.Scheduler.timeout);
*
* @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence with time interval information on values.
*/
observableProto.timeInterval = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimeIntervalObservable(this, scheduler);
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
var GenerateAbsoluteObservable = (function (__super__) {
inherits(GenerateAbsoluteObservable, __super__);
function GenerateAbsoluteObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateAbsoluteObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, new Date(this._s.now()), scheduleRecursive);
};
return GenerateAbsoluteObservable;
}(ObservableBase));
/**
* GenerateAbsolutes an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithAbsoluteTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return new Date(); }
* });
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateAbsoluteObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var GenerateRelativeObservable = (function (__super__) {
inherits(GenerateRelativeObservable, __super__);
function GenerateRelativeObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateRelativeObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, 0, scheduleRecursive);
};
return GenerateRelativeObservable;
}(ObservableBase));
/**
* Generates an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithRelativeTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return 500; }
* );
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateRelativeObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var DelaySubscription = (function(__super__) {
inherits(DelaySubscription, __super__);
function DelaySubscription(source, dt, s) {
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DelaySubscription.prototype.subscribeCore = function (o) {
var d = new SerialDisposable();
d.setDisposable(this._s.scheduleFuture([this.source, o, d], this._dt, scheduleMethod));
return d;
};
function scheduleMethod(s, state) {
var source = state[0], o = state[1], d = state[2];
d.setDisposable(source.subscribe(o));
}
return DelaySubscription;
}(ObservableBase));
/**
* Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.delaySubscription(5000); // 5s
* 2 - res = source.delaySubscription(5000, Rx.Scheduler.default); // 5 seconds
*
* @param {Number} dueTime Relative or absolute time shift of the subscription.
* @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delaySubscription = function (dueTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new DelaySubscription(this, dueTime, scheduler);
};
var SkipLastWithTimeObservable = (function (__super__) {
inherits(SkipLastWithTimeObservable, __super__);
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
return SkipLastWithTimeObservable;
}(ObservableBase));
var SkipLastWithTimeObserver = (function (__super__) {
inherits(SkipLastWithTimeObserver, __super__);
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
__super__.call(this);
}
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
return SkipLastWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for skipping elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
*/
observableProto.skipLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipLastWithTimeObservable(this, duration, scheduler);
};
var TakeLastWithTimeObservable = (function (__super__) {
inherits(TakeLastWithTimeObservable, __super__);
function TakeLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
TakeLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeLastWithTimeObserver(o, this._d, this._s));
};
return TakeLastWithTimeObservable;
}(ObservableBase));
var TakeLastWithTimeObserver = (function (__super__) {
inherits(TakeLastWithTimeObserver, __super__);
function TakeLastWithTimeObserver(o, d, s) {
this._o = o;
this._d = d;
this._s = s;
this._q = [];
__super__.call(this);
}
TakeLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._q.shift();
}
};
TakeLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0) {
var next = this._q.shift();
if (now - next.interval <= this._d) { this._o.onNext(next.value); }
}
this._o.onCompleted();
};
return TakeLastWithTimeObserver;
}(AbstractObserver));
/**
* Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeLastWithTimeObservable(this, duration, scheduler);
};
/**
* Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastBufferWithTime = function (duration, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (o) {
var q = [];
return source.subscribe(function (x) {
var now = scheduler.now();
q.push({ interval: now, value: x });
while (q.length > 0 && now - q[0].interval >= duration) {
q.shift();
}
}, function (e) { o.onError(e); }, function () {
var now = scheduler.now(), res = [];
while (q.length > 0) {
var next = q.shift();
now - next.interval <= duration && res.push(next.value);
}
o.onNext(res);
o.onCompleted();
});
}, source);
};
var TakeWithTimeObservable = (function (__super__) {
inherits(TakeWithTimeObservable, __super__);
function TakeWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
function scheduleMethod(s, o) {
o.onCompleted();
}
TakeWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(o, this._d, scheduleMethod),
this.source.subscribe(o)
);
};
return TakeWithTimeObservable;
}(ObservableBase));
/**
* Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.takeWithTime(5000, [optional scheduler]);
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
*/
observableProto.takeWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeWithTimeObservable(this, duration, scheduler);
};
var SkipWithTimeObservable = (function (__super__) {
inherits(SkipWithTimeObservable, __super__);
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
__super__.call(this);
}
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
return SkipWithTimeObservable;
}(ObservableBase));
var SkipWithTimeObserver = (function (__super__) {
inherits(SkipWithTimeObserver, __super__);
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
* @description
* Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
* This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
* may not execute immediately, despite the zero due time.
*
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
* @param {Number} duration Duration for skipping elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
*/
observableProto.skipWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipWithTimeObservable(this, duration, scheduler);
};
var SkipUntilWithTimeObservable = (function (__super__) {
inherits(SkipUntilWithTimeObservable, __super__);
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
__super__.call(this);
}
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
return SkipUntilWithTimeObservable;
}(ObservableBase));
var SkipUntilWithTimeObserver = (function (__super__) {
inherits(SkipUntilWithTimeObserver, __super__);
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipUntilWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
*
* @examples
* 1 - res = source.skipUntilWithTime(new Date(), [scheduler]);
* 2 - res = source.skipUntilWithTime(5000, [scheduler]);
* @param {Date|Number} startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped until the specified start time.
*/
observableProto.skipUntilWithTime = function (startTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipUntilWithTimeObservable(this, startTime, scheduler);
};
/**
* Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
* @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
* @param {Scheduler} [scheduler] Scheduler to run the timer on.
* @returns {Observable} An observable sequence with the elements taken until the specified end time.
*/
observableProto.takeUntilWithTime = function (endTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var source = this;
return new AnonymousObservable(function (o) {
return new BinaryDisposable(
scheduler.scheduleFuture(o, endTime, function (_, o) { o.onCompleted(); }),
source.subscribe(o));
}, source);
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
return Rx;
}));
================================================
FILE: dist/rx.virtualtime.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
defaultSubComparer = Rx.helpers.defaultSubComparer,
notImplemented = Rx.helpers.notImplemented;
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
/** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
Rx.HistoricalScheduler = (function (__super__) {
inherits(HistoricalScheduler, __super__);
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function HistoricalScheduler(initialClock, comparer) {
var clock = initialClock == null ? 0 : initialClock;
var cmp = comparer || defaultSubComparer;
__super__.call(this, clock, cmp);
}
var HistoricalSchedulerProto = HistoricalScheduler.prototype;
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
HistoricalSchedulerProto.add = function (absolute, relative) {
return absolute + relative;
};
HistoricalSchedulerProto.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
* @memberOf HistoricalScheduler
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
HistoricalSchedulerProto.toRelativeTime = function (timeSpan) {
return timeSpan;
};
return HistoricalScheduler;
}(Rx.VirtualTimeScheduler));
return Rx;
}));
================================================
FILE: doc/api/config/readme.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Reactive Extensions Configuration #
Configuration information for the Reactive Extensions for JavaScript
## Documentation ##
- [`Rx.config.Promise`](#rxconfigpromise)
- [`Rx.config.useNativeEvents`](#rxconfigusenativeevents)
* * *
### `Rx.config.Promise`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
Sets the default Promise type to be used when the [`toPromise`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/topromise.md) method is called. Note that the Promise implementation must conform to the ES6 specification. Some of those supported libraries are [Q](https://github.com/kriskowal/q), [RSVP](https://github.com/tildeio/rsvp.js), [when.js](https://github.com/cujojs/when) among others. If not specified, this defaults to the native ES6 Promise, if available, else will throw an error.
#### Example
```js
Rx.config.Promise = RSVP.Promise;
var p = Rx.Observable.just(1).toPromise()
.then(function (value) { console.log('Value: %s', s); });
// => Value: 1
```
* * *
### `Rx.config.useNativeEvents`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromevent.js "View in source") [Ⓣ][1]
Determines whether the [`fromEvent`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromevent.md) method uses native DOM events only and disregards the referenced supported libraries such as [jQuery](http://jquery.com/), [Zepto.js](http://zeptojs.com/), [AngularJS](https://angularjs.org/), [Ember.js](http://emberjs.com/) and [Backbone.js](http://backbonejs.org)
#### Example
For example, we could have jQuery referenced as part of our project, however, we only want native DOM events.
```html
```
We can do this by setting the `Rx.config.useNativeEvents` flag to `true`.
```js
Rx.config.useNativeEvents = true;
Rx.Observable.fromEvent(document, 'mousemove')
.subscribe(function (e) {
console.log('ClientX: %d, ClientY: %d', e.clientX, e.clientY);
});
```
* * *
================================================
FILE: doc/api/core/notification.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Notification object #
Represents a notification to an observer.
## Usage ##
This can be dematerialized into an Observable.
```js
var source = Rx.Observable
.of(
Rx.Notification.createOnNext(42),
Rx.Notification.createOnCompleted()
)
.dematerialize();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`notification.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js)
## `Notification Methods`
- [`createOnCompleted`](#rxnotificationcreateoncompleted)
- [`createOnError`](#rxnotificationcreateonerrorexception)
- [`createOnNext`](#rxnotificationcreateonnextvalue)
## `Notification Instance Methods`
- [`accept`](#rxnotificationprototypeacceptobserver--onnext-onerror-oncompleted)
- [`toObservable`](#rxnotificationprototypetoobservablescheduler)
## `Notification Properties`
- [`error`](#error)
- [`kind`](#kind)
- [`value`](#value)
## _Notification Methods_ ##
### `Rx.Notification.createOnCompleted()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js#L113-L134 "View in source")
Creates an object that represents an OnCompleted notification to an observer.
#### Returns
`Notification` - The OnCompleted notification.
#### Example
```js
var source = Rx.Observable
.of(Rx.Notification.createOnCompleted() )
.dematerialize();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Completed
```
***
### `Rx.Notification.createOnError(exception)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js#L85-L107 "View in source")
Creates an object that represents an OnError notification to an observer.
### Arguments
1. `error`: `Any` - The exception contained in the notification.
#### Returns
`Notification` - The OnError notification containing the exception.
#### Example
```js
var source = Rx.Observable
.of(Rx.Notification.createOnError(new Error('woops')) )
.dematerialize();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Error: Error: woops
```
### Location
- rx.js
***
### `Rx.Notification.createOnNext(value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js#L56-L178 "View in source")
Creates an object that represents an OnNext notification to an observer.
### Arguments
1. `value`: `Any` - The value contained in the notification.
#### Returns
`Notification`: The onNext notification containing the value.
#### Example
```js
var source = Rx.Observable
.of(
Rx.Notification.createOnNext(42),
Rx.Notification.createOnCompleted()
)
.dematerialize();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
***
## _Notification Instance Methods_ ##
### `Rx.Notification.prototype.accept(observer | onNext, onError, onCompleted)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js "View in source")
Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result or the individual functions given.
### Arguments
1. `[observer]`: `Observer` Observer to invoke the notification on.
OR
1. `onNext`: `Function` - Function to invoke for an `onNext` notification.
2. `onError`: `Function` - Function to invoke for an `onError` notification.
3. `onCompleted`: `Function` - Function to invoke for an `onCompleted` notification.
#### Returns
`Any`: Result produced by the observation.
#### Example
```js
/* Using an observer */
var observer = Rx.Observer.create(function (x) { return x; });
var notification = Rx.Notification.createOnNext(42);
console.log(notification.accept(observer));
// => 42
/* Using a function */
var notification = Rx.Notification.createOnNext(42);
console.log(notification.accept(function (x) { return x; }))
// => 42
```
***
### `Rx.Notification.prototype.toObservable([scheduler])`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js "View in source")
Returns an observable sequence with a single notification.
### Arguments
1. `[scheduler = Rx.Scheduler.immediate]` `Scheduler`: Scheduler to send out the notification calls on.
#### Returns
`Observable`: The observable sequence that surfaces the behavior of the notification upon subscription.
#### Example
```js
/* Without a scheduler */
var source = Rx.Notification.createOnNext(42)
.toObservable();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
/* With a scheduler */
var source = Rx.Notification.createOnError(new Error('error!'))
.toObservable(Rx.Scheduler.default);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Error: Error: error!
```
***
## _Notification Properties_ ##
### `error`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js "View in source")
Gets the exception from the OnError notification.
#### Returns
`Any`: The Error from the `onError` notification.
#### Example
```js
var notification = Rx.Notification.createOnError(new Error('invalid'));
console.log(notification.error);
// => Error: invalid
```
***
### `kind`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js "View in source")
Gets the kind from the notification which denotes 'N' for OnNext, 'E' for OnError and 'C' for OnCompleted.
#### Returns
`String`: The kind from the notification which denotes 'N' for OnNext, 'E' for OnError and 'C' for OnCompleted.
#### Example
```js
var notification = Rx.Notification.createOnCompleted();
console.log(notification.kind);
// => C
```
***
### `value`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/notification.js "View in source")
Gets the value from the `onNext` notification.
#### Returns
`Any`: The value from the `onNext` notification.
#### Example
```js
var notification = Rx.Notification.createOnNext(42);
console.log(notification.value);
// => 42
```
***
================================================
FILE: doc/api/core/observable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Observable object #
The Observable object represents a push based collection.
The Observer and Observable interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. The Observable object represents the object that sends notifications (the provider); the Observer object represents the class that receives them (the observer).
## `Observable Methods`
- [`amb`](operators/amb.md)
- [`case`](operators/case.md)
- [`catch`](operators/catch.md)
- [`combineLatest`](operators/combinelatest.md)
- [`concat`](operators/concat.md)
- [`create`](operators/create.md)
- [`defer`](operators/defer.md)
- [`empty`](operators/empty.md)
- [`for`](operators/for.md)
- [`forkJoin`](operators/forkjoin.md)
- [`from`](operators/from.md)
- [`fromCallback`](operators/fromcallback.md)
- [`fromEvent`](operators/fromevent.md)
- [`fromEventPattern`](operators/fromeventpattern.md)
- [`fromNodeCallback`](operators/fromnodecallback.md)
- [`fromPromise`](operators/frompromise.md)
- [`generate`](operators/generate.md)
- [`generateWithAbsoluteTime`](operators/generatewithabsolutetime.md)
- [`generateWithRelativeTime`](operators/generatewithrelativetime.md)
- [`if`](operators/if.md)
- [`interval`](operators/interval.md)
- [`just`](operators/return.md)
- [`merge`](operators/merge.md)
- [`mergeDelayError`](operators/mergedelayerror.md)
- [`never`](operators/never.md)
- [`of`](operators/of.md)
- [`ofWithScheduler`](operators/ofwithscheduler.md)
- [`onErrorResumeNext`](operators/onerrorresumenext.md)
- [`pairs`](operators/pairs.md)
- [`range`](operators/range.md)
- [`repeat`](operators/repeat.md)
- [`return`](operators/return.md)
- [`spawn`](operators/spawn.md)
- [`start`](operators/start.md)
- [`startAsync`](operators/startasync.md)
- [`throw`](operators/throw.md)
- [`timer`](operators/timer.md)
- [`toAsync`](operators/toasync.md)
- [`using`](operators/using.md)
- [`when`](operators/when.md)
- [`while`](operators/while.md)
- [`wrap`](operators/wrap.md)
- [`zip`](operators/zip.md)
## `Observable Instance Methods`
- [`amb`](operators/ambproto.md)
- [`and`](operators/and.md)
- [`asObservable`](operators/asobservable.md)
- [`average`](operators/average.md)
- [`buffer`](operators/buffer.md)
- [`bufferWithCount`](operators/bufferwithcount.md)
- [`bufferWithTime`](operators/bufferwithtime.md)
- [`bufferWithTimeOrCount`](operators/bufferwithtimeorcount.md)
- [`catch`](operators/catchproto.md)
- [`combineLatest`](operators/combinelatestproto.md)
- [`concat`](operators/concatproto.md)
- [`concatAll`](operators/concatall.md)
- [`concatMap`](operators/concatmap.md)
- [`concatMapObserver`](operators/concatmapobserver.md)
- [`connect`](operators/connect.md)
- [`controlled`](operators/controlled.md)
- [`count`](operators/count.md)
- [`debounce`](operators/debounce.md)
- [`defaultIfEmpty`](operators/defaultifempty.md)
- [`delay`](operators/delay.md)
- [`delaySubscription`](operators/delaysubscription.md)
- [`dematerialize`](operators/dematerialize.md)
- [`distinct`](operators/distinct.md)
- [`distinctUntilChanged`](operators/distinctuntilchanged.md)
- [`do`](operators/do.md)
- [`doOnCompleted`](operators/dooncompleted.md)
- [`doOnError`](operators/doonerror.md)
- [`doOnNext`](operators/doonnext.md)
- [`doWhile`](operators/dowhile.md)
- [`elementAt`](operators/elementat.md)
- [`every`](operators/every.md)
- [`expand`](operators/expand.md)
- [`extend`](operators/manyselect.md)
- [`filter`](operators/where.md)
- [`finally`](operators/finally.md)
- [`find`](operators/find.md)
- [`findIndex`](operators/findindex.md)
- [`first`](operators/first.md)
- [`flatMap`](operators/selectmany.md)
- [`flatMapFirst`](operators/flatmapfirst.md)
- [`flatMapLatest`](operators/flatmaplatest.md)
- [`flatMapObserver`](operators/flatmapobserver.md)
- [`flatMapWithMaxConcurrent`](operators/flatmapwithmaxconcurrent.md)
- [`forkJoin`](operators/forkjoinproto.md)
- [`groupBy`](operators/groupby.md)
- [`groupByUntil`](operators/groupbyuntil.md)
- [`groupJoin`](operators/groupjoin.md)
- [`ignoreElements`](operators/ignoreelements.md)
- [`includes`](operators/includes.md)
- [`indexOf`](operators/indexof.md)
- [`isEmpty`](operators/isempty.md)
- [`join`](operators/join.md)
- [`jortSort`](operators/jortsort.md)
- [`jortSortUntil`](operators/jortsortuntil.md)
- [`last`](operators/last.md)
- [`lastIndexOf`](operators/lastindexof.md)
- [`let`](operators/let.md)
- [`manySelect`](operators/manyselect.md)
- [`map`](operators/select.md)
- [`max`](operators/max.md)
- [`maxBy`](operators/maxby.md)
- [`merge`](operators/mergeproto.md)
- [`mergeAll`](operators/mergeall.md)
- [`min`](operators/min.md)
- [`minBy`](operators/minby.md)
- [`multicast`](operators/multicast.md)
- [`observeOn`](operators/observeon.md)
- [`onErrorResumeNext`](operators/onerrorresumenextproto.md)
- [`pairwise`](operators/pairwise.md)
- [`partition`](operators/partition.md)
- [`pausable`](operators/pausable.md)
- [`pausableBuffered`](operators/pausablebuffered.md)
- [`pluck`](operators/pluck.md)
- [`publish`](operators/publish.md)
- [`publishLast`](operators/publishlast.md)
- [`publishValue`](operators/publishvalue.md)
- [`reduce`](operators/reduce.md)
- [`refCount`](operators/refcount.md)
- [`repeat`](operators/repeatproto.md)
- [`repeatWhen`](operators/repeatwhen.md)
- [`replay`](operators/replay.md)
- [`retry`](operators/retry.md)
- [`retryWhen`](operators/retrywhen.md)
- [`sample`](operators/sample.md)
- [`scan`](operators/scan.md)
- [`select`](operators/select.md)
- [`selectConcat`](operators/concatmap.md)
- [`selectConcatObserver`](operators/concatmapobserver.md)
- [`selectMany`](operators/selectmany.md)
- [`selectManyObserver`](operators/flatmapobserver.md)
- [`sequenceEqual`](operators/sequenceequal.md)
- [`share`](operators/share.md)
- [`shareReplay`](operators/sharereplay.md)
- [`shareValue`](operators/sharevalue.md)
- [`single`](operators/single.md)
- [`singleInstance`](operators/singleinstance.md)
- [`skip`](operators/skip.md)
- [`skipLast`](operators/skiplast.md)
- [`skipLastWithTime`](operators/skiplastwithtime.md)
- [`skipUntil`](operators/skipuntil.md)
- [`skipUntilWithTime`](operators/skipuntilwithtime.md)
- [`skipWhile`](operators/skipwhile.md)
- [`slice`](operators/slice.md)
- [`some`](operators/some.md)
- [`startWith`](operators/startwith.md)
- [`subscribe | forEach`](operators/subscribe.md)
- [`subscribeOn`](operators/subscribeon.md)
- [`subscribeOnCompleted`](operators/subscribeoncompleted.md)
- [`subscribeOnError`](operators/subscribeonerror.md)
- [`subscribeOnNext`](operators/subscribeonnext.md)
- [`sum`](operators/sum.md)
- [`switch | switchLatest`](operators/switch.md)
- [`switchFirst`](operators/switchfirst.md)
- [`take`](operators/take.md)
- [`takeLast`](operators/takelast.md)
- [`takeLastBuffer`](operators/takelastbuffer.md)
- [`takeLastBufferWithTime`](operators/takelastbufferwithtime.md)
- [`takeLastWithTime`](operators/takelastwithtime.md)
- [`takeUntil`](operators/takeuntil.md)
- [`takeUntilWithTime`](operators/takeuntilwithtime.md)
- [`takeWhile`](operators/takewhile.md)
- [`tap`](operators/do.md)
- [`tapOnCompleted`](operators/dooncompleted.md)
- [`tapOnError`](operators/doonerror.md)
- [`tapOnNext`](operators/doonnext.md)
- [`throttle`](operators/throttle.md)
- [`timeInterval`](operators/timeinterval.md)
- [`timeout`](operators/timeout.md)
- [`timeoutWithSelector`](operators/timeoutwithselector.md)
- [`timestamp`](operators/timestamp.md)
- [`toArray`](operators/toarray.md)
- [`toMap`](operators/tomap.md)
- [`toPromise`](operators/topromise.md)
- [`toSet`](operators/toset.md)
- [`transduce`](operators/transduce.md)
- [`where`](operators/where.md)
- [`window`](operators/window.md)
- [`windowWithCount`](operators/windowwithcount.md)
- [`windowWithTime`](operators/windowwithtime.md)
- [`windowWithTimeOrCount`](operators/windowwithtimeorcount.md)
- [`withLatestFrom`](operators/withlatestfrom.md)
- [`zip`](operators/zipproto.md)
- [`zipIterable`](operators/zipiterable.md)
================================================
FILE: doc/api/core/observer.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Observer object #
The Observer object provides support for push-style iteration over an observable sequence.
The Observer and Objects interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. The Observable object represents the object that sends notifications (the provider); the Observer object represents the class that receives them (the observer).
## `Observer Methods`
- [`create`](#rxobservercreateonnext-onerror-oncompleted)
- [`fromNotifier`](#rxobserverfromotifierhandler)
## `Observer Instance Methods`
- [`asObserver`](#rxobserverprototypeasobserver)
- [`checked`](#rxobserverprototypechecked)
- [`notifyOn`](#rxobserverprototypenotifyonscheduler)
- [`onCompleted`](#rxobserverprototypeoncompleted)
- [`onError`](#rxobserverprototypeonerrorerror)
- [`onNext`](#rxobserverprototypeonnextvalue)
- [`toNotifier`](#rxobserverprototypetonotifier)
## _Observer Methods_ ##
### `Rx.Observer.create([onNext], [onError], [onCompleted])`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1828-L1833 "View in source") [Ⓣ][1]
Creates an observer from the specified `onNext`, `onError`, and `onCompleted` actions.
#### Arguments
1. `[onNext]` *(Function)*: Observer's onNext action implementation.
2. `[onError]` *(Function)*: Observer's onError action implementation.
3. `[onCompleted]` *(Function)*: Observer's onCompleted action implementation.
#### Returns
*(Observer)*: The observer object implemented using the given actions.
#### Example
```js
var source = Rx.Observable.return(42);
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
var subscription = source.subscribe(observer);
// => Next: 42
// => Completed
```
### Location
- rx.js
* * *
### `Rx.Observer.fromNotifier(handler, [thisArg])`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1843-L1851 "View in source") [Ⓣ][1]
Creates an observer from a notification callback.
#### Arguments
1. `handler` *(Function)*: Function that handles a notification.
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing `handler`.
#### Returns
*(Observer)*: The observer object that invokes the specified handler using a notification corresponding to each message it receives.
#### Example
```js
function handler(n) {
// Handle next calls
if (n.kind === 'N') {
console.log('Next: ' + n.value);
}
// Handle error calls
if (n.kind === 'E') {
console.log('Error: ' + n.exception);
}
// Handle completed
if (n.kind === 'C') {
console.log('Completed')
}
}
Rx.Observer.fromNotifier(handler).onNext(42);
// => Next: 42
Rx.Observer.fromNotifier(handler).onError(new Error('error!!!'));
// => Error: Error: error!!!
Rx.Observer.fromNotifier(handler).onCompleted();
// => false
```
### Location
- rx.js
* * *
## _Observer Instance Methods_ ##
### `Rx.Observer.prototype.asObserver()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1810-L1812 "View in source") [Ⓣ][1]
Hides the identity of an observer.
#### Returns
*(Observer)*: An observer that hides the identity of the specified observer.
#### Example
```js
function SampleObserver () {
Rx.Observer.call(this);
this.isStopped = false;
}
SampleObserver.prototype = Object.create(Rx.Observer.prototype);
SampleObserver.prototype.constructor = SampleObserver;
Object.defineProperties(SampleObserver.prototype, {
onNext: {
value: function (x) {
if (!this.isStopped) {
console.log('Next: ' + x);
}
}
},
onError: {
value: function (err) {
if (!this.isStopped) {
this.isStopped = true;
console.log('Error: ' + err);
}
}
},
onCompleted: {
value: function () {
if (!this.isStopped) {
this.isStopped = true;
console.log('Completed');
}
}
}
});
var sampleObserver = new SampleObserver();
var source = sampleObserver.asObserver();
console.log(source === sampleObserver);
// => false
```
### Location
- rx.js
* * *
### `Rx.Observer.prototype.checked()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1819 "View in source") [Ⓣ][1]
Checks access to the observer for grammar violations. This includes checking for multiple `onError` or `onCompleted` calls, as well as reentrancy in any of the observer methods.
If a violation is detected, an Error is thrown from the offending observer method call.
#### Returns
*(Observer)*: An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
#### Example
```js
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x)
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
var checked = observer.checked();
checked.onNext(42);
// => Next: 42
checked.onCompleted();
// => Completed
// Throws Error('Observer completed')
checked.onNext(42);
```
### Location
- rx.js
* * *
### `Rx.Observer.prototype.notifyOn(scheduler)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1858-1860 "View in source") [Ⓣ][1]
Schedules the invocation of observer methods on the given scheduler.
#### Arguments
1. `scheduler` *(Scheduler)*: Scheduler to schedule observer messages on.
#### Returns
*(Observer)*: Observer whose messages are scheduled on the given scheduler.
#### Example
```js
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x)
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
// Notify on timeout scheduler
var timeoutObserver = observer.notifyOn(Rx.Scheduler.timeout);
timeoutObserver.onNext(42);
// => Next: 42
```
### Location
- rx.js
* * *
### `Rx.Observer.prototype.onCompleted()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1899-L1904 "View in source") [Ⓣ][1]
Notifies the observer of the end of the sequence.
#### Example
```js
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x)
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
observer.onCompleted();
// => Completed
```
### Location
- rx.js
* * *
### `Rx.Observer.prototype.onError(error)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1889-L1894 "View in source") [Ⓣ][1]
Notifies the observer that an exception has occurred.
#### Arguments
1. `error` *(Any)*: The error that has occurred.
#### Example
```js
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x)
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
observer.onError(new Error('error!!'));
// => Error: Error: error!!
```
### Location
- rx.js
* * *
### `Rx.Observer.prototype.onNext(value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1881-L1883 "View in source") [Ⓣ][1]
Notifies the observer of a new element in the sequence.
#### Arguments
1. `value` *(Any)*: Next element in the sequence.
#### Example
```js
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x)
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
observer.onNext(42);
// => Next: 42
```
### Location
- rx.js
* * *
### `Rx.Observer.prototype.toNotifier()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L1801-L1804 "View in source") [Ⓣ][1]
Creates a notification callback from an observer.
#### Returns
*(Function)*: The function that forwards its input notification to the underlying observer.
#### Example
```js
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x)
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
var notifier = observer.toNotifier();
// Invoke with onNext
notifier(Rx.Notification.createOnNext(42));
// => Next: 42
// Invoke with onCompleted
notifier(Rx.Notification.createOnCompleted());
// => Completed
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/core/operators/amb.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.amb(...args)` [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/amb.js "View in source")
Propagates the observable sequence or Promise that reacts first. "amb" stands for [ambiguous](http://blogs.msdn.com/b/jeffva/archive/2009/11/18/amb-materialize-and-dematerialize.aspx).
#### Arguments
1. `args` *(Array|arguments)*: Observable sources or Promises competing to react first either as an array or arguments.
#### Returns
*(`Observable`)*: An observable sequence that surfaces any of the given sequences, whichever reacted first.
#### Example
```js
/* Using Observable sequences */
var source = Rx.Observable.amb(
Rx.Observable.timer(500).select(function () { return 'foo'; }),
Rx.Observable.timer(200).select(function () { return 'bar'; })
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: bar
// => Completed
/* Using Promises and Observables */
var source = Rx.Observable.amb(
RSVP.Promise.resolve('foo'),
Rx.Observable.timer(200).select(function () { return 'bar'; })
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: foo
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/amb.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/amb.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [`/tests/observable/amb.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/amb.js)
================================================
FILE: doc/api/core/operators/ambproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.amb(rightSource)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/ambproto.js "View in source")
Propagates the observable sequence that reacts first.
#### Arguments
1. `rightSource` *(`Observable`)*: Second observable sequence.
#### Returns
*(`Observable`)*: An observable sequence that surfaces either of the given sequences, whichever reacted first.
#### Example
```js
var first = Rx.Observable.timer(300).map(function () { return 'first'; });
var second = Rx.Observable.timer(500).map(function () { return 'second'; });
var source = first.amb(second);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: first
// => Completed
```
### Location
File:
- [/src/core/linq/observable/ambproto.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/ambproto.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/amb.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/amb.js)
================================================
FILE: doc/api/core/operators/and.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.and(rightSource)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/and.js "View in source")
Propagates the observable sequence that reacts first.
#### Arguments
1. `right` *(`Observable`)*: Observable sequence to match with the current sequence.
#### Returns
*(`Pattern`)*: Pattern object that matches when both observable sequences have an available value.
#### Example
```js
// Choice of either plan, the first set of timers or second set
var source = Rx.Observable.when(
Rx.Observable.timer(200).and(Rx.Observable.timer(300)).thenDo(function (x, y) { return 'first'; }),
Rx.Observable.timer(400).and(Rx.Observable.timer(500)).thenDo(function (x, y) { return 'second'; })
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: first
// => Next: second
// => Completed
```
### Location
File:
- [/src/core/linq/observable/and.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/and.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.joinpatterns.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.joinpatterns.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-JoinPatterns`](http://www.nuget.org/packages/RxJS-JoinPatterns)
Unit Tests:
- [/tests/observable/when.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/when.js)
================================================
FILE: doc/api/core/operators/asobservable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.asObservable()` [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/asobservable.js "View in source")
Hides the identity of an observable sequence.
#### Returns
*(`Observable`)*: An observable sequence that hides the identity of the source sequence.
#### Example
```js
// Create subject
var subject = new Rx.AsyncSubject();
// Send a value
subject.onNext(42);
subject.onCompleted();
// Hide its type
var source = subject.asObservable();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/asobservable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/asobservable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [`/tests/observable/asobservable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/asobservable.js)
================================================
FILE: doc/api/core/operators/average.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.average([selector], [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/average.js "View in source")
Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present.
#### Arguments
1. `[selector]` *(`Function`)*: A transform function to apply to each element.
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing `selector`.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with the average of the sequence of values.
#### Example
```js
// Without a selector
var source = Rx.Observable.range(0, 9).average();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 4
// => Completed
// With a selector
var arr = [
{ value: 1 },
{ value: 2 },
{ value: 3 }
];
var source = Rx.Observable.from(arr).average(function (x) {
return x.value;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/average.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/average.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/average.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/average.js)
================================================
FILE: doc/api/core/operators/buffer.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.buffer()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js#L572-L585 "View in source")
The `buffer` method periodically gathers items emitted by a source Observable into buffers, and emits these buffers as its own emissions.
Note that if the source Observable issues an `onError` notification, `buffer` will pass on this notification immediately without first emitting the buffer it is in the process of assembling, even if that buffer contains items that were emitted by the source Observable before it issued the error notification.
There are a number of ways with which you can regulate how `buffer` gathers items from the source Observable into buffers:
#### With buffer closing selector
```js
Rx.Observable.prototype.buffer(bufferClosingSelector);
```
Returns an Observable that emits buffers of items it collects from the source `Observable`. The resulting `Observable` emits connected, non-overlapping buffers. It emits the current buffer and replaces it with a new buffer whenever the `Observable` produced by the specified `bufferClosingSelector` emits an item.
#### Arguments
1. `bufferClosingSelector` *(`Function`)*: A function invoked to define the closing of each produced window.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
// With closings
var source = Rx.Observable.timer(0, 50)
.buffer(function () { return Rx.Observable.timer(125); })
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2
// => Next: 3,4,5
// => Next: 6,7
// => Completed
```
#### With buffer opening and buffer closing selector
```js
Rx.Observable.prototype.buffer(bufferOpenings, bufferClosingSelector);
```
This version of `buffer` monitors an `Observable`, `bufferOpenings`, that emits Observable objects. Each time it observes such an emitted object, it creates a new bundle to begin collecting items emitted by the source Observable and it passes the `bufferOpenings` Observable into the `bufferClosingSelector` function. That function returns an `Observable`. `buffer` monitors that `Observable` and when it detects an emitted object, it closes its bundle and emits it as its own emission.
1. `bufferOpenings` *(`Observable`)*: Observable sequence whose elements denote the creation of new windows.
2. `bufferClosingSelector` *(`Function`)*: A function invoked to define the closing of each produced window.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
/* Using Openings and Closing Selector */
var openings = Rx.Observable.interval(200);
var source = Rx.Observable.interval(50)
.buffer(openings, function (x) { return Rx.Observable.timer(x + 100); })
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 3,4
// => Next: 7,8
// => Next: 11,12
// => Completed
```
#### With boundaries
```js
Rx.Observable.prototype.buffer(bufferBoundaries);
```
Returns an `Observable` that emits non-overlapping buffered items from the source `Observable` each time the specified boundary `Observable` emits an item.
#### Arguments
1. `bufferBoundaries` *(`Observable`)*: Sequence of buffer boundary markers. The current buffer is closed and a new buffer is opened upon receiving a boundary marker.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
/* Using buffer boundaries */
var openings = Rx.Observable.interval(500);
// Convert the window to an array
var source = Rx.Observable.timer(0, 100)
.buffer(openings)
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2,3,4
// => Next: 5,6,7,8,9,10
// => Next: 11,12,13,14,15
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/buffer.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/buffer.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/buffer.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/buffer.js)
================================================
FILE: doc/api/core/operators/bufferwithcount.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.bufferWithCount(count, [skip])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/bufferwithcount.js)
Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
#### Arguments
1. `count` *(`Function`)*: Length of each buffer.
2. `[skip]` *(`Function`)*: Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
#### Returns
*(`Observable`)*: An observable sequence of buffers.
#### Example
```js
/* Without a skip */
var source = Rx.Observable.range(1, 6)
.bufferWithCount(2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1,2
// => Next: 3,4
// => Next: 5,6
// => Completed
/* Using a skip */
var source = Rx.Observable.range(1, 6)
.bufferWithCount(2, 1);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1,2
// => Next: 2,3
// => Next: 3,4
// => Next: 4,5
// => Next: 5,6
// => Next: 6
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/bufferwithcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/bufferwithcount.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/bufferwithcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/bufferwithcount.js)
================================================
FILE: doc/api/core/operators/bufferwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.bufferWithTime(timeSpan, [timeShift | scheduler], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/bufferwithtime.js "View in source")
Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
#### Arguments
1. `timeSpan` *(`Number`)*: Length of each buffer (specified as an integer denoting milliseconds).
2. `[timeShift]` *(`Number`)*: Interval between creation of consecutive buffers (specified as an integer denoting milliseconds).
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence of buffers.
#### Example
```js
/* Without a skip */
var source = Rx.Observable.interval(100)
.bufferWithTime(500)
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2,3
// => Next: 4,5,6,7,8
// => Next: 9,10,11,12,13
// => Completed
/* Using a skip */
var source = Rx.Observable.interval(100)
.bufferWithTime(500, 100)
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2,3,4
// => Next: 0,1,2,3,4,5
// => Next: 2,3,4,5,6
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/bufferwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/bufferwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).time.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | rx.lite.compat.js
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/bufferwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/bufferwithtime.js)
================================================
FILE: doc/api/core/operators/bufferwithtimeorcount.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.bufferWithTimeOrCount(timeSpan, count, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/bufferwithtimeorcount.js "View in source")
Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
#### Arguments
1. `timeSpan` *(`Number`)*: Maximum time length of a buffer.
2. `count` *(`Number`)*: Maximum element count of a buffer.
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence of buffers.
#### Example
```js
/* Hitting the count buffer first */
var source = Rx.Observable.interval(100)
.bufferWithTimeOrCount(500, 3)
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2
// => Next: 3,4,5
// => Next: 6,7,8
// => Completed
```
### Location
File:
- [/src/core/linq/observable/bufferwithtimeorcount.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/bufferwithtimeorcount.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).time.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | rx.lite.compat.js
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/bufferwithtimeorcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/bufferwithtimeorcount.js)
================================================
FILE: doc/api/core/operators/case.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.case(selector, sources, [elseSource|scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/case.js "View in source")
Uses selector to determine which source in sources to use. There is an alias 'switchCase' for browsers Next: 42
//=> Completed
```
### Location
File:
- [`/src/core/linq/observable/case.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/case.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- If using `rx.expermental.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/case.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/case.js)
================================================
FILE: doc/api/core/operators/catch.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.catch(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/catch.js "View in source")
Continues an observable sequence that is terminated by an exception with the next observable sequence.
#### Arguments
1. `args` *(`Array` | `arguments`)*: Observable sequences to catch exceptions for.
#### Returns
*(`Observable`)*: An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.
#### Example
```js
var obs1 = Rx.Observable.throw(new Error('error'));
var obs2 = Rx.Observable.return(42);
var source = Rx.Observable.catch(obs1, obs2);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/catch.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/catch.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/catch.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/catch.js)
================================================
FILE: doc/api/core/operators/catchproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.catch(second | handler)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js#L3107-L3112 "View in source")
Continues an observable sequence that is terminated by an exception with the next observable sequence.
#### Arguments
Using another Observable:
- `second` *(`Observable`)*: A second observable sequence used to produce results when an error occurred in the first sequence.
Using a handler:
- `handler` *(`Function`)*: Exception handler function that returns an observable sequence given the error that occurred in the first sequence
#### Returns
*(`Observable`)*: An observable sequence containing the first sequence's elements, followed by the elements of the handler sequence in case an exception occurred.
#### Example
```js
/* Using a second observable */
var source = Rx.Observable.throw(new Error()).catch(Rx.Observable.just(42));
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
/* Using a handler function */
var source = Rx.Observable.throw(new TimeoutError())
.catch(function (e) {
var returnValue;
if (e instanceof TimeoutError) { return Rx.Observable.just(42); }
return Rx.Observable.throw(e);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/catchproto.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/catchproto.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/catch.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/catch.js)
================================================
FILE: doc/api/core/operators/combinelatest.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.combineLatest(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/combinelatest.js "View in source")
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. This can be in the form of an argument list of observables or an array. If the result selector is omitted, a list with the elements will be yielded.
#### Arguments
1. `args` *(arguments | Array)*: An array or arguments of Observable sequences.
2. `[resultSelector]` *(`Function`)*: Function to invoke whenever either of the sources produces an element. If omitted, a list with the elements will be yielded.
#### Returns
*(`Observable`)*: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
#### Example
```js
/* Have staggering intervals */
var source1 = Rx.Observable.interval(100)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(150)
.map(function (i) { return 'Second: ' + i; });
// Combine latest of source1 and source2 whenever either gives a value
var source = Rx.Observable.combineLatest(
source1,
source2
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', JSON.stringify(x));
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: ["First: 0","Second: 0"]
// => Next: ["First: 1","Second: 0"]
// => Next: ["First: 1","Second: 1"]
// => Next: ["First: 2","Second: 1"]
// => Completed
/* Have staggering intervals */
var source1 = Rx.Observable.interval(100)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(150)
.map(function (i) { return 'Second: ' + i; });
// Combine latest of source1 and source2 whenever either gives a value with a selector
var source = Rx.Observable.combineLatest(
source1,
source2,
function (s1, s2) { return s1 + ', ' + s2; }
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: First: 0, Second: 0
// => Next: First: 1, Second: 0
// => Next: First: 1, Second: 1
// => Next: First: 2, Second: 1
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/combinelatest.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/combinelatest.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/combinelatest.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/combinelatest.js)
================================================
FILE: doc/api/core/operators/combinelatestproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.combineLatest(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/combinelatestproto.js "View in source")
Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element (so long as each of the source observable sequences has emitted at least one element). This can be in the form of an argument list of observables or an array. If the result selector is omitted, a list with the elements will be yielded.
#### Arguments
1. `args` *(arguments | Array)*: An array or arguments of Observable sequences.
2. `[resultSelector]` *(`Function`)*: Function to invoke whenever either of the sources produces an element. If omitted, a list with the elements will be yielded.
#### Returns
*(`Observable`)*: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
#### Example
```js
/* Have staggering intervals */
var source1 = Rx.Observable.interval(100)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(150)
.map(function (i) { return 'Second: ' + i; });
// Combine latest of source1 and source2 whenever either gives a value with selector
var source = source1.combineLatest(
source2
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: First: 0,Second: 0
// => Next: First: 1,Second: 0
// => Next: First: 1,Second: 1
// => Next: First: 2,Second: 1
// => Completed
/* Have staggering intervals */
var source1 = Rx.Observable.interval(100)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(150)
.map(function (i) { return 'Second: ' + i; });
// Combine latest of source1 and source2 whenever either gives a value
var source = source1.combineLatest(
source2,
function (s1, s2) { return s1 + ', ' + s2; }
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: First: 0, Second: 0
// => Next: First: 1, Second: 0
// => Next: First: 1, Second: 1
// => Next: First: 2, Second: 1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/combinelatestproto.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/combinelatestproto.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/combinelatest.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/combinelatest.js)
================================================
FILE: doc/api/core/operators/concat.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.concat(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/concat.js "View in source")
Concatenates all of the specified observable sequences, as long as the previous observable sequence terminated successfully.
#### Arguments
1. `args` *(`Array` | `arguments`)*: Observable sequences or Promises to concatenate.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of each given sequence, in sequential order.
#### Example
```js
/* Using Observable sequences */
var source1 = Rx.Observable.return(42);
var source2 = Rx.Observable.return(56);
var source = Rx.Observable.concat(source1, source2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 56
// => Completed
/* Using Promises and Observable sequences */
var source1 = Rx.Observable.return(42);
var source2 = RSVP.Promise.resolve(56);
var source = Rx.Observable.concat(source1, source2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 56
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/concat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/concat.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/concat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/concat.js)
================================================
FILE: doc/api/core/operators/concatall.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.concatAll()` ###
### `Rx.Observable.prototype.concatObservable()` **DEPRECATED** ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatall.js "View in source")
Concatenates a sequence of observable sequences or promises into a single observable sequence.
#### Returns
*(`Observable`)*: The observable sequence that merges the elements of the inner sequences.
#### Example
```js
var source = Rx.Observable.range(0, 3)
.map(function (x) { return Rx.Observable.range(x, 3); })
.concatAll();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
#### Location
File:
- [/src/core/linq/observable/concatall.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatall.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/concat.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/concat.js)
================================================
FILE: doc/api/core/operators/concatmap.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.concatMap(selector, [resultSelector], [thisArg])`
### `Rx.Observable.prototype.selectConcat(selector, [resultSelector], [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatmap.js "View in source")
This is an alias for the `selectConcat` method. This can be one of the following:
Projects each element of an observable sequence to an observable sequence and concatenates the resulting observable sequences or Promises or array/iterable into one observable sequence.
```js
source.concatMap(function (x, i) { return Rx.Observable.range(0, x); });
source.concatMap(function (x, i) { return Promise.resolve(x + 1); });
source.concatMap(function (x, i) { return [x, i]; });
```
Projects each element of an observable sequence or Promise to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and concatenates the results into one observable sequence.
```js
source.concatMap(function (x, i) { return Rx.Observable.range(0, x); }, function (x, y, ix, iy) { return x + y + ix + iy; });
source.concatMap(function (x, i) { return Promise.resolve(x + i); }, function (x, y, ix, iy) { return x + y + ix + iy; });
source.concatMap(function (x, i) { return [x, i]; }, function (x, y, ix, iy) { return x + y + ix + iy; });
```
Projects each element of the source observable sequence to the other observable sequence or Promise or array/iterable and merges the resulting observable sequences into one observable sequence.
```js
source.concatMap(Rx.Observable.of(1,2,3));
source.concatMap(Promise.resolve(42));
source.concatMap([1,2,3]);
```
#### Arguments
1. `selector` *(`Function` | `Iterable` | `Promise`)*: An Object to project to the sequence or a transform function to apply to each element or an observable sequence to project each element from the source sequence onto. The selector is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[resultSelector]` *(`Function`)*: A transform function to apply to each element of the intermediate sequence. The resultSelector is called with the following information:
1. the value of the outer element
2. the value of the inner element
3. the index of the outer element
4. the index of the inner element
3. `[thisArg]` *(`Any`)*: If `resultSelector` is not `Function`, Object to use as `this` when executing `selector`.
#### Returns
*(`Observable`)*: An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.concatMap(function (x, i) {
return Rx.Observable
.interval(100)
.take(x).map(function() { return i; });
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 2
// => Next: 3
// => Next: 3
// => Next: 3
// => Next: 4
// => Next: 4
// => Next: 4
// => Next: 4
// => Completed
/* Using a promise */
var source = Rx.Observable.of(1,2,3,4)
.concatMap(function (x, i) {
return Promise.resolve(x + i);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 3
// => Next: 5
// => Next: 7
// => Completed
/* Using an array */
var source = Rx.Observable.of(1,2,3)
.concatMap(
function (x, i) { return [x,i]; },
function (x, y, ix, iy) { return x + y + ix + iy; }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 2
// => Next: 5
// => Next: 5
// => Next: 8
// => Next: 8
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/concatmap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatmap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/concatmap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/concatmap.js)
================================================
FILE: doc/api/core/operators/concatmapobserver.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.concatMapObserver(onNext, onError, onCompleted, [thisArg])`
### `Rx.Observable.prototype.selectConcatObserver(onNext, onError, onCompleted, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatmapobserver.js "View in source")
Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
#### Arguments
1. `onNext` *(`Function`)*: A transform function to apply to each element. The selector is called with the following information:
1. the value of the element
2. the index of the element
2. `onError` *(`Function`)*: A transform function to apply when an error occurs in the source sequence.
3. `onCompleted` *(`Function`)*: A transform function to apply when the end of the source sequence is reached.
4. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the transform functions.
#### Returns
*(`Observable`)*: An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
#### Example
```js
var source = Rx.Observable.range(1, 3)
.concatMapObserver(
function (x, i) {
return Rx.Observable.repeat(x, i);
},
function (err) {
return Rx.Observable.return(42);
},
function () {
return Rx.Observable.empty();
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 3
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/concatmapobserver.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatmapobserver.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [`/tests/observable/concatmapobserver.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/concatmapobserver.js)
================================================
FILE: doc/api/core/operators/concatproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.concat(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatproto.js "View in source")
Concatenates all the observable sequences. This takes in either an array or variable arguments to concatenate.
#### Arguments
1. `args` *(arguments | Array)*: An array or arguments of Observable sequences.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of each given sequence, in sequential order.
#### Example
```js
var source = Rx.Observable
.return(42)
.concat(Rx.Observable.return(56), Rx.Observable.return(72));
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 56
// => Next: 72
// => Completed
// With a promise
var source = Rx.Observable.just(42)
.concat(Promise.resolve(42));
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/concatproto.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/concatproto.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/concat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/concat.js)
================================================
FILE: doc/api/core/operators/connect.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `ConnectableObservable.prototype.connect()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js#L504 "View in source")
Connects the observable wrapper to its source. All subscribed observers will receive values from the underlying observable sequence as long as the connection is established.
#### Returns
*(Disposable)*: Disposable object used to disconnect the observable wrapper from its source, causing subscribed observer to stop receiving values from the underlying observable sequence.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.do(function (x) {
console.log('Side effect');
});
var published = source.publish();
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
// Connect the source
var connection = published.connect();
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed
// => Completed
```
### Location
File:
- [`/src/core/linq/connectableobservable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/connectableobservable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
Unit Tests:
- [`/tests/observable/connectableobservable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/connectableobservable.js)
================================================
FILE: doc/api/core/operators/controlled.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.controlled([enableQueue])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/backpressure/controlled.js "View in source")
Attaches a controller to the observable sequence with the ability to queue.
#### Arguments
1. `[enableQueue]` *(Boolean)*: Whether to enable queueing. If not specified, defaults to true.
#### Returns
*(`Observable`)*: An observable sequence which can be used to request values from the sequence.
#### Example
```js
var source = Rx.Observable.range(0, 10).controlled();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
source.request(2);
// => Next: 0
// => Next: 1
```
### Location
File:
- [`/src/core/backpressure/controlled.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/backpressure/controlled.js)
Dist:
- [`rx.backpressure.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.backpressure.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-BackPressure`](http://www.nuget.org/packages/RxJS-BackPressure/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/controlled.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/controlled.js)
================================================
FILE: doc/api/core/operators/count.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.count([predicate], [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/count.js "View in source")
Returns an observable sequence containing a value that represents how many elements in the specified observable sequence satisfy a condition if provided, else the count of items.
#### Arguments
1. `[predicate]` *(`Function`)*: A function to test each element for a condition. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing `predicate`.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function if provided, else the count of items in the sequence.
#### Example
```js
/* Without a predicate */
var source = Rx.Observable.range(0, 10).count();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 10
// => Completed
/* With a predicate */
var source = Rx.Observable.range(0, 10)
.count(function (x) { return x % 2 === 0; });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 5
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/count.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/count.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/count.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/count.js)
================================================
FILE: doc/api/core/operators/create.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.create(subscribe)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/create.js "View in source")
Creates an observable sequence from a specified subscribe method implementation. This is an alias for the `createWithDisposable` method
#### Arguments
1. `subscribe` *(`Function`)*: Implementation of the resulting observable sequence's subscribe method, optionally returning a function that will be wrapped in a disposable object. This could also be a disposable object.
#### Returns
*(`Observable`)*: The observable sequence with the specified implementation for the subscribe method.
#### Example
```js
/* Using a function */
var source = Rx.Observable.create(function (observer) {
observer.onNext(42);
observer.onCompleted();
// Note that this is optional, you do not have to return this if you require no cleanup
return function () {
console.log('disposed');
};
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
subscription.dispose();
// => disposed
/* Using a disposable */
var source = Rx.Observable.create(function (observer) {
observer.onNext(42);
observer.onCompleted();
// Note that this is optional, you do not have to return this if you require no cleanup
return Rx.Disposable.create(function () {
console.log('disposed');
});
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/create.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/create.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/create.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/create.js)
================================================
FILE: doc/api/core/operators/debounce.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.debounce(dueTime, [scheduler])` ###
### `Rx.Observable.prototype.debounce(durationSelector)` ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/debounce.js "View in source")
Emits an item from the source Observable after a particular timespan has passed without the Observable omitting any other items.
--OR--
Ignores values from an observable sequence which are followed by another value within a computed debounced duration.
#### Arguments
If using a relative due time:
1. `dueTime` *(`Number`)*: Duration of the throttle period for each value (specified as an integer denoting milliseconds).
2. `[scheduler]` *(`Any`)*: Scheduler to run the throttle timers on. If not specified, the default scheduler is used.
If using the duration selector function:
1. `durationSelector` *(`Function`)*: Selector function to retrieve a sequence indicating the throttle duration for each given element.
#### Returns
*(`Observable`)*: The debounced sequence.
#### Example
```js
var times = [
{ value: 0, time: 100 },
{ value: 1, time: 600 },
{ value: 2, time: 400 },
{ value: 3, time: 700 },
{ value: 4, time: 200 }
];
// Delay each item by time and project value;
var source = Rx.Observable.from(times)
.flatMap(function (item) {
return Rx.Observable
.of(item.value)
.delay(item.time);
})
.debounce(500 /* ms */);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 3
// => Completed
/* Using Selector */
var array = [
800,
700,
600,
500
];
var source = Rx.Observable.for(
array,
function (x) { return Rx.Observable.timer(x) }
)
.map(function(x, i) { return i; })
.debounce(function (x) { return Rx.Observable.timer(700); });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/debounce.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/debounce.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/debounce.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/debounce.js)
================================================
FILE: doc/api/core/operators/defaultifempty.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.defaultIfEmpty([defaultValue])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/defaultifempty.js "View in source")
Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
#### Arguments
1. `[defaultValue=null]` *(`Any`)*: The value to return if the sequence is empty. If not provided, this defaults to null.
#### Returns
*(`Observable`)*: An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
#### Example
```js
/* Without a default value */
var source = Rx.Observable.empty().defaultIfEmpty();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: null
// => Completed
/* With a defaultValue */
var source = Rx.Observable.empty().defaultIfEmpty(false);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: false
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/defaultifempty.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/defaultifempty.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/defaultifempty.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/defaultifempty.js)
================================================
FILE: doc/api/core/operators/defer.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.defer(observableFactory)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/defer.js "View in source")
Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
#### Arguments
1. `observableFactory` *(`Function`)*: Observable factory function to invoke for each observer that subscribes to the resulting sequence.
#### Returns
*(`Observable`)*: An observable sequence whose observers trigger an invocation of the given observable factory function.
#### Example
```js
/* Using an observable sequence */
var source = Rx.Observable.defer(function () {
return Rx.Observable.return(42);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
/* Using a promise */
var source = Rx.Observable.defer(function () {
return RSVP.Promise.resolve(42);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/defer.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/defer.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/defer.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/defer.js)
================================================
FILE: doc/api/core/operators/delay.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.delay(dueTime, [scheduler])`
### `Rx.Observable.prototype.delay([subscriptionDelay], delayDurationSelector`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/delay.js "View in source")
Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved.
--OR--
Time shifts the observable sequence based on a subscription delay and a delay selector function for each element.
#### Arguments
For delays with an absolute or relative time:
1. `dueTime` *(Date | Number)*: Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
2. `[scheduler]` *(`Scheduler`)*: Scheduler to run the delay timers on. If not specified, the default scheduler is used.
For delays with a delay selector function:
1. `[subscriptionDelay]` *(`Observable`)*: Sequence indicating the delay for the subscription to the source.
2. `delayDurationSelector` *(`Function`)*: Selector function to retrieve a sequence indicating the delay for each given element.
#### Returns
*(`Observable`)*: Time-shifted sequence.
#### Example
```js
/* Using an absolute time to delay by a second */
var source = Rx.Observable.range(0, 3)
.delay(new Date(Date.now() + 1000));
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
/* Using an relative time to delay by a second */
var source = Rx.Observable.range(0, 3)
.delay(1000);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
/* With subscriptionDelay */
var source = Rx.Observable
.range(0, 3)
.delay(
Rx.Observable.timer(300),
function (x) { return Rx.Observable.timer(x * 400); }
)
.timeInterval()
.map(function (x) { return x.value + ':' + x.interval; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0:300
// => Next: 1:400
// => Next: 2:400
// => Completed
/* Without subscriptionDelay */
var source = Rx.Observable
.range(0, 3)
.delay(function (x) { return Rx.Observable.timer(x * 400); })
.timeInterval()
.map(function (x) { return x.value + ':' + x.interval; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0:0
// => Next: 1:400
// => Next: 2:400
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/delay.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/delay.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).time.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | rx.lite.compat.js
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/delay.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/delay.js)
================================================
FILE: doc/api/core/operators/delaysubscription.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.delaySubscription(dueTime, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/delaysubscription.js "View in source")
Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
This operator is more efficient than `delay` but postpones all side-effects of subscription and affects error propagation timing.
The side-effects of subscribing to the source sequence will be run on the specified scheduler. Observer callbacks will not be affected.
#### Arguments
1. `dueTime` *(`Number | Date`)*: Relative (Number) or Absolute (Date) time shift of the subscription.
2. `[scheduler]` *(`Scheduler`)*: Scheduler to run the subscription delay timer on. If not specified, the default scheduler is used.
#### Returns
*(`Observable`)*: Time-shifted sequence.
#### Example
```js
var start = Date.now()
var source = Rx.Observable
.range(0, 3)
.delaySubscription(5000);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s, %s', x, Date.now() - start);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
//=> Next: 0, 5001
//=> Next: 1, 5002
//=> Next: 2, 5003
//=> Completed
```
### Location
File:
- [`/src/core/linq/observable/delaysubscription.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/delaysubscription.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/delaysubscription.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/delaysubscription.js)
================================================
FILE: doc/api/core/operators/dematerialize.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.dematerialize()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/dematerialize.js "View in source")
Dematerializes the explicit notification values of an observable sequence as implicit notifications.
#### Returns
*(`Observable`)*: An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
#### Example
```js
var source = Rx.Observable
.from([
Rx.Notification.createOnNext(42),
Rx.Notification.createOnError(new Error('woops'))
])
.dematerialize();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Error: Error: woops
```
### Location
File:
- [`/src/core/linq/observable/dematerialize.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/dematerialize.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/materialize.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/materialize.js)
================================================
FILE: doc/api/core/operators/distinct.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.distinct([keySelector], [comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/distinct.js "View in source")
Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer. Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
#### Arguments
1. `[keySelector]` *(`Function`)*: A function to compute the comparison key for each element.
2. `[comparer]` *(`Function`)*: Used to compare objects for equality. If not provided, defaults to an equality comparer function.
#### Returns
*(`Observable`)*: An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
#### Example
```js
/* Without key selector */
var source = Rx.Observable.of(42, 24, 42, 24)
.distinct();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 24
// => Completed
/* With key selector */
var source = Rx.Observable.of({value: 42}, {value: 24}, {value: 42}, {value: 24})
.distinct(function (x) { return x.value; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: { value: 42 }
// => Next: { value: 24 }
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/distinct.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/distinct.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
- [`rx.lite.extras.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/distinct.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/distinct.js)
================================================
FILE: doc/api/core/operators/distinctuntilchanged.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.distinctUntilChanged([keySelector], [comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/distinctuntilchanged.js "View in source")
Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer.
#### Arguments
1. `[keySelector]` *(`Function`)*: A function to compute the comparison key for each element. If not provided, it projects the value.
2. `[comparer]` *(`Function`)*: Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
#### Returns
*(`Observable`)*: An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
#### Example
```js
/* Without key selector */
var source = Rx.Observable.of(42, 42, 24, 24)
.distinctUntilChanged();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 24
// => Completed
/* With key selector */
var source = Rx.Observable.of({value: 42}, {value: 42}, {value: 24}, {value: 24})
.distinctUntilChanged(function (x) { return x.value; });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: { value: 42 }
// => Next: { value: 24 }
// => Completed
/* With comparer */
var source = Rx.Observable.of({value: 42}, {value: 42}, {value: 24}, {value: 24})
.distinctUntilChanged(function (x) { return x.value; }, function (a,b) { return a !== b; });
var subscription = source.subscribe(
function (x) {
console.dir('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: { value: 42 }
// => Next: { value: 42 }
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/distinctuntilchanged.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/distinctuntilchanged.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/distinctuntilchanged.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/distinctuntilchanged.js)
================================================
FILE: doc/api/core/operators/do.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.do([observer] | [onNext], [onError], [onCompleted])` ###
### `Rx.Observable.prototype.tap([observer] | [onNext], [onError], [onCompleted])` ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js "View in source")
Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
There is an alias to this method `doAction` for browsers Do Next: 0
// => Next: 0
// => Do Next: 1
// => Next: 1
// => Do Next: 2
// => Next: 2
// => Do Completed
// => Completed
/* Using an observer */
var observer = Rx.Observer.create(
function (x) { console.log('Do Next: %s', x); },
function (err) { console.log('Do Error: %s', err); },
function () { console.log('Do Completed'); }
);
var source = Rx.Observable.range(0, 3)
.do(observer);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Do Next: 0
// => Next: 0
// => Do Next: 1
// => Next: 1
// => Do Next: 2
// => Next: 2
// => Do Completed
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/tap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/do.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/do.js)
================================================
FILE: doc/api/core/operators/dooncompleted.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.doOnCompleted(onCompleted, [thisArg])`
### `Rx.Observable.prototype.tapOnCompleted(onCompleted, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js "View in source")
Invokes an action upon graceful termination of the observable sequence.
This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
#### Arguments
1. `oncompleted` *(`Function`)*: Function to invoke upon graceful termination of the observable sequence.
2. [`thisArg`] *(Any)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: The source sequence with the side-effecting behavior applied.
#### Example
```js
/* Using a function */
var source = Rx.Observable.range(0, 3)
.doOnCompleted(
function () { console.log('Do Completed'); }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Do Completed
// => Completed
/* Using a thisArg */
var source = Rx.Observable.range(0, 3)
.doOnCompleted(
function () { this.log('Do Completed'); },
console
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Do Completed
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/tap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/do.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/do.js)
================================================
FILE: doc/api/core/operators/doonerror.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.doOnError(onError, [thisArg])`
### `Rx.Observable.prototype.tapOnError(onError, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js "View in source")
Invokes an action upon exceptional termination of the observable sequence.
This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
#### Arguments
1. `onError` *(`Function`)*: Function to invoke upon exceptional termination of the observable sequence.
2. [`thisArg`] *(Any)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: The source sequence with the side-effecting behavior applied.
#### Example
```js
/* Using a function */
var source = Rx.Observable.throw(new Error())
.doOnError(
function (err) { console.log('Do Error: %s', err); }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Do Error: Error
// => Error: Error
/* Using a thisArg */
var source = Rx.Observable.throw(new Error())
.doOnError(
function (err) { this.log('Do Error: %s', err); },
console
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Do Error: Error
// => Error: Error
```
### Location
File:
- [`/src/core/perf/operators/tap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/do.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/do.js)
================================================
FILE: doc/api/core/operators/doonnext.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.doOnNext(onNext, [thisArg])`
### `Rx.Observable.prototype.tapOnNext(onNext, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js "View in source")
Invokes an action for each element of the observable sequence.
This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
#### Arguments
1. `onNext` *(`Function`)*: Function to invoke for each element in the observable sequence.
2. [`thisArg`] *(Any)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: The source sequence with the side-effecting behavior applied.
#### Example
```js
/* Using a function */
var source = Rx.Observable.range(0, 3)
.doOnNext(
function () { console.log('Do Next: %s', x); }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Do Next: 0
// => Next: 0
// => Do Next: 1
// => Next: 1
// => Do Next: 2
// => Next: 2
// => Completed
/* Using a thisArg */
var source = Rx.Observable.range(0, 3)
.doOnNext(
function () { this.log('Do Next: %s', x); },
console
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Do Next: 0
// => Next: 0
// => Do Next: 1
// => Next: 1
// => Do Next: 2
// => Next: 2
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/tap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/tap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/do.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/do.js)
================================================
FILE: doc/api/core/operators/dowhile.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.doWhile(condition)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/dowhile.js "View in source")
Repeats source as long as condition holds emulating a do while loop.
#### Arguments
1. `condition` *(`Function`)*: The condition which determines if the source will be repeated.
#### Returns
*(`Observable`)*: An observable sequence whose observers trigger an invocation of the given observable factory function.
#### Example
```js
var i = 0;
var source = Rx.Observable.return(42).doWhile(function (x) { return ++i < 2; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/dowhile.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/dowhile.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/dowhile.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/dowhile.js)
================================================
FILE: doc/api/core/operators/elementat.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.elementAt(index, [defaultValue])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/elementat.js "View in source")
Returns the element at a specified index in a sequence. If the specified index is out of bounds and no default value was given `onError` will be called with an error, however, if a default value has been specified, that value will be returned via an `onNext` call.
#### Arguments
1. `index` *(`Number`)*: The zero-based index of the element to retrieve.
2. `[defaultValue]` *(`Any`)*: Default value if no such element exists.
#### Returns
*(`Observable`)*: An observable sequence that produces the element at the specified position in the source sequence. If the specified index is out of bounds and no default value was given `onError` will be called with an error, however, if a default value has been specified, that value will be returned via an `onNext` call.
#### Example
```js
/* Finds an index */
var source = Rx.Observable.from([1,2,3,4])
.elementAt(1);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Completed
/* With default value */
var source = Rx.Observable.from([1,2,3,4])
.elementAt(4, 42);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/elementat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/elementat.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/elementat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/elementat.js)
================================================
FILE: doc/api/core/operators/empty.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.empty([scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/empty.js "View in source")
Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
#### Arguments
1. `[scheduler=Rx.Scheduler.immediate]` *(`Scheduler`)*: Scheduler to send the termination call on.
#### Returns
*(`Observable`)*: An observable sequence with no elements.
#### Example
```js
var source = Rx.Observable.empty();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Completed
```
### Location
File:
- [/src/core/perf/operators/empty.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/empty.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/empty.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/empty.js)
================================================
FILE: doc/api/core/operators/every.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.every(predicate, [thisArg])` ##
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/every.js "View in source")
Determines whether all elements of an observable sequence satisfy a condition.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each element for a condition.
2. `[thisArg]` *(`Function`)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.
#### Example
```js
var source = Rx.Observable.of(1,2,3,4,5)
.every(function (x) {
return x < 6;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/every.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/every.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/every.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/every.js)
================================================
FILE: doc/api/core/operators/expand.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.expand(selector, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/expand.js "View in source")
Expands an observable sequence by recursively invoking selector.
#### Arguments
1. `selector` *(`Function`)*: Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
2. [`scheduler=Rx.Scheduler.immediate`] *(`Scheduler`)*: Scheduler on which to perform the expansion. If not provided, this defaults to the immediate scheduler.
#### Returns
*(`Observable`)*: An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.
#### Example
```js
var source = Rx.Observable.return(42)
.expand(function (x) { return Rx.Observable.return(42 + x); })
.take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Next: 84
// => Next: 126
// => Next: 168
// => Next: 210
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/expand.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/expand.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/expand.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/expand.js)
================================================
FILE: doc/api/core/operators/finally.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.finally(action)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/finally.js "View in source")
Invokes a specified action after the source observable sequence terminates gracefully or exceptionally. There is an alias called `finallyAction` for browsers Error: Error
// => Finally
```
### Location
File:
- [`/src/core/perf/operators/finally.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/finally.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/finally.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/finally.js)
================================================
FILE: doc/api/core/operators/find.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.find(predicate, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/find.js)
Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each source element for a condition; The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Observable`)*: An Observable sequence with the first element that matches the conditions defined by the specified predicate, if found; otherwise, an empty sequence.
#### Example
```js
/* Found an element */
var array = [1,2,3,4];
var source = Rx.Observable.from(array)
.find(function (x, i, obs) { return x === 1; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Completed
/* Not found */
var array = [1,2,3,4];
var source = Rx.Observable.from(array)
.find(function (x, i, obs) { return x === 5; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/find.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/find.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/find.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/find.js)
================================================
FILE: doc/api/core/operators/findindex.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.findIndex(predicate, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/findindex.js "View in source")
Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each source element for a condition; The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Observable`)*: An Observable sequence with the first element that matches the conditions defined by the specified predicate, if found; otherwise, undefined.
#### Example
```js
/* Found an element */
var array = [1,2,3,4];
var source = Rx.Observable.from(array)
.findIndex(function (x, i, obs) { return x === 1; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Completed
/* Not found */
var array = [1,2,3,4];
var source = Rx.Observable.from(array)
.findIndex(function (x, i, obs) { return x === 5; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: -1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/findindex.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/findindex.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/findindex.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/findindex.js)
================================================
FILE: doc/api/core/operators/first.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.first([predicate], [thisArg], [defaultValue])`
### `Rx.Observable.prototype.first([settings])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/first.js "View in source")
Returns the first element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists. If no default value is given, then `onError` will be called.
#### Arguments
`Rx.Observable.prototype.first([predicate], [thisArg], [defaultValue])`
1. `[predicate]` *(`Function`)*: A predicate function to evaluate for elements in the source sequence. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
3. `[defaultValue]` *(`Any`)*: Default value if no such element exists.
`Rx.Observable.prototype.first([settings])`
1. `[settings]` *(`Object`)*: An object with the following fields
- `[predicate]` *(`Function`)*: A predicate function to evaluate for elements in the source sequence. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
- `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
- `[defaultValue]` *(`Any`)*: Default value if no such element exists.
#### Returns
*(`Observable`)*: An observable sequence that contains elements from the input sequence that satisfy the condition.
#### Example
```js
/* Without a predicate */
var source = Rx.Observable.range(0, 10).first();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Completed
/* With a predicate */
var source = Rx.Observable.range(0, 10)
.first(function (x, idx, obs) { return x % 2 === 1; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Completed
/* With a default value */
var source = Rx.Observable.range(0, 10)
.first({
predicate: function (x, idx, obs) { return x > 10; },
defaultValue: 42
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/first.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/first.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/first.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/first.js)
================================================
FILE: doc/api/core/operators/flatmapfirst.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.flatMapFirst(selector, [thisArg])`
### `Rx.Observable.prototype.selectSwitchFirst(selector, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmapfirst.js "View in source")
Transform the items emitted by an Observable into Observables, and mirror those items emitted by the most-recently transformed Observable.
The `flatMapFirst` operator is similar to the `flatMap` and `concatMap` methods described above, however, rather than emitting all of the items emitted by all of the Observables that the operator generates by transforming items from the source `Observable`, `flatMapFirst` instead propagates the first `Observable` exclusively until it completes before it begins subscribes to the next `Observable`. Observables that come before the current `Observable` completes will be dropped and will not propagate.
#### Arguments
1. `selector` *(`Function`)*: A transform function to apply to each source element. The callback has the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Observable`)*: An Observable sequence that is the result of concatenating non-overlapping items emitted by an Observable of Observables.
#### Example
```js
//Generate an event every 100 milliseconds
var source = Rx.Observable.generateWithRelativeTime(
0,
function(x) {return x < 5; },
function(x) {return x + 1; },
function(x) {return x; },
function(x) {return 100; })
.flatMapFirst(function(value) {
//Observable takes 150 milliseconds to complete
return Rx.Observable.timer(150).map(value);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %d', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// Next: 0
// Next: 2
// Next: 4
// Completed
```
### Location
File:
- [`/src/core/perf/operators/flatmapfirst.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmapfirst.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental/)
Unit Tests:
- None
================================================
FILE: doc/api/core/operators/flatmaplatest.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.flatMapLatest(selector, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmaplatest.js "View in source")
Transform the items emitted by an Observable into Observables, and mirror those items emitted by the most-recently transformed Observable.
The `flatMapLatest` operator is similar to the `flatMap` and `concatMap` methods described above, however, rather than emitting all of the items emitted by all of the Observables that the operator generates by transforming items from the source `Observable`, `flatMapLatest` instead emits items from each such transformed `Observable` only until the next such `Observable` is emitted, then it ignores the previous one and begins emitting items emitted by the new one.
#### Arguments
1. `selector` *(`Function`)*: A transform function to apply to each source element. The callback has the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Observable`)*: An observable sequence which transforms the items emitted by an Observable into Observables, and mirror those items emitted by the most-recently transformed Observable.
#### Example
```js
var source = Rx.Observable
.range(1, 3)
.flatMapLatest(function(x) {
return Rx.Observable.from([x + 'a', x + 'b']);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// Next: 1a
// Next: 2a
// Next: 3a
// Next: 3b
// Completed
```
### Location
File:
- [`/src/core/perf/operators/flatmaplatest.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmaplatest.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- None
================================================
FILE: doc/api/core/operators/flatmapobserver.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.flatMapObserver(onNext, onError, onCompleted, [thisArg])`
### `Rx.Observable.prototype.selectManyObserver(onNext, onError, onCompleted, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/selectmanyobserver.js "View in source")
Projects each notification of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
#### Arguments
1. `onNext` *(`Function`)*: A transform function to apply to each element. The selector is called with the following information:
1. the value of the element
2. the index of the element
2. `onError` *(`Function`)*: A transform function to apply when an error occurs in the source sequence.
3. `onCompleted` *(`Function`)*: A transform function to apply when the end of the source sequence is reached.
4. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the transform functions.
#### Returns
*(`Observable`)*: An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
#### Example
```js
var source = Rx.Observable.range(1, 3)
.flatMapObserver(
function (x, i) {
return Rx.Observable.repeat(x, i);
},
function (err) {
return Rx.Observable.return(42);
},
function () {
return Rx.Observable.empty();
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 3
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/selectmanyobserver.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/selectmanyobserver.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [`/tests/observable/selectmanyobserver.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/selectmanyobserver.js)
================================================
FILE: doc/api/core/operators/flatmapwithmaxconcurrent.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.flatMapWithMaxConcurrent(maxConcurrent, selector, [resultSelector], [thisArg])`
### `Rx.Observable.prototype.selectWithMaxConcurrent(maxConcurrent, selector, [resultSelector], [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmapwithmaxconcurrent.js "View in source")
This is an alias for the `selectWithMaxConcurrent` method. This can be one of the following:
Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence with the given concurrency limit.
```js
source.flatMapWithMaxConcurrent(10, function (x, i) { return Rx.Observable.range(0, x); });
source.flatMapWithMaxConcurrent(1, function (x, i) { return Promise.resolve(x + 1); });
source.flatMapWithMaxConcurrent(1, function (x, i) { return [x, i]; });
```
Projects each element of an observable sequence or Promise to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence with the given concurrency limit.
```js
source.flatMapWithMaxConcurrent(10, function (x, i) { return Rx.Observable.range(0, x); }, function (x, y, ix, iy) { return x + y + ix + iy; });
source.flatMapWithMaxConcurrent(1, function (x, i) { return Promise.resolve(x + i); }, function (x, y, ix, iy) { return x + y + ix + iy; });
source.flatMapWithMaxConcurrent(1, function (x, i) { return [x, i]; }, function (x, y, ix, iy) { return x + y + ix + iy; });
```
Projects each element of the source observable sequence to the other observable sequence or Promise or array/iterable and merges the resulting observable sequences into one observable sequence with the given max concurrency limit.
```js
source.flatMapWithMaxConcurrent(1, Rx.Observable.of(1,2,3));
source.flatMapWithMaxConcurrent(1, Promise.resolve(42));
source.flatMapWithMaxConcurrent(1, [1,2,3]);
```
#### Arguments
1. `maxConcurrent` *(`Number`)*: Maximum number of inner observable sequences being subscribed to concurrently.
2. `selector` *(`Function` | `Iterable` | `Promise`)*: An Object to project to the sequence or a transform function to apply to each element or an observable sequence to project each element from the source sequence onto. The selector is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
3. `[resultSelector]` *(`Function`)*: A transform function to apply to each element of the intermediate sequence. The resultSelector is called with the following information:
1. the value of the outer element
2. the value of the inner element
3. the index of the outer element
4. the index of the inner element
4. `[thisArg]` *(`Any`)*: If `resultSelector` is not `Function`, Object to use as `this` when executing `selector`.
#### Returns
*(`Observable`)*: An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.flatMapWithMaxConcurrent(2, function (x, i) {
return Rx.Observable
.interval(100)
.take(x).map(function() { return i; });
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 2
// => Next: 3
// => Next: 4
// => Next: 3
// => Next: 4
// => Next: 4
// => Next: 4
// => Completed
/* Using a promise */
var source = Rx.Observable.of(1,2,3,4)
.flatMapWithMaxConcurrent(1, function (x, i) {
return Promise.resolve(x + i);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 3
// => Next: 5
// => Next: 7
// => Completed
/* Using an array */
var source = Rx.Observable.of(1,2,3)
.flatMapWithMaxConcurrent(
1,
function (x, i) { return [x,i]; },
function (x, y, ix, iy) { return x + y + ix + iy; }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 2
// => Next: 5
// => Next: 5
// => Next: 8
// => Next: 8
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/flatmapwithmaxconcurrent.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmapwithmaxconcurrent.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete/)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental/)
Unit Tests:
- None
================================================
FILE: doc/api/core/operators/for.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.for(sources, resultSelector, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/for.js "View in source")
Concatenates the observable sequences or Promises obtained by running the specified result selector for each element in source.
There is an alias for this method called `forIn` for browsers Next: 1
// => Next: 2
// => Next: 3
// => Completed
/* Using Promises */
var array = [1, 2, 3];
var source = Rx.Observable.for(
array,
function (x) {
return RSVP.Promise.resolve(x);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [/src/core/linq/observable/for.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/for.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- If using `rx.experimental.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/for.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/for.js)
================================================
FILE: doc/api/core/operators/forkjoin.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.forkJoin(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/forkjoin.js "View in source")
Runs all observable sequences in parallel and collect their last elements.
#### Arguments
1. `args` *(Arguments | Array)*: An array or arguments of Observable sequences or Promises to collect the last elements for.
2. `resultSelector`: `Function` - The result selector from all the values produced. If not specified, `forkJoin` will return the results as an array.
#### Returns
*(`Observable`)*: An observable sequence with an array collecting the last elements of all the input sequences or the result of the result selector if specified.
#### Example
```js
/* Without a selector */
var source = Rx.Observable.forkJoin(
Rx.Observable.return(42),
Rx.Observable.range(0, 10),
Rx.Observable.from([1,2,3]),
RSVP.Promise.resolve(56)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: [42, 9, 3, 56]
// => Completed
var source = Rx.Observable.forkJoin(
Rx.Observable.just(42),
Rx.Observable.just(56),
function (x, y) { return x + y; }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 98
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/forkjoin.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/forkjoin.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- If using `rx.experimental.js` - [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/forkjoin.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/forkjoin.js)
================================================
FILE: doc/api/core/operators/forkjoinproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.forkJoin(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/forkjoinproto.js "View in source")
Runs all observable sequences in parallel and collect their last elements.
#### Arguments
1. `args`: `Arguments` | `Array` - An array or arguments of Observable sequences or Promises to collect the last elements for.
2. `resultSelector`: `Function` - The result selector from all the values produced. If not specified, `forkJoin` will return the results as an array.
#### Returns
*(`Observable`)*: An observable sequence with an array collecting the last elements of all the input sequences or the result of the result selector if specified.
#### Example
```js
// With a selector
var source = Rx.Observable.just(42).forkJoin(
Rx.Observable.range(0, 3),
function (s1, s2) { return s1 + s2; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 44
// => Completed
// Without a selector
var source = Rx.Observable.just(42).forkJoin(
Rx.Observable.range(0, 3));
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: [42, 2]
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/forkjoinproto.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/forkjoinproto.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/forkjoin.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/forkjoin.js)
================================================
FILE: doc/api/core/operators/from.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.from(iterable, [mapFn], [thisArg], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/from.js 'View in source')
This method creates a new Observable sequence from an array-like or iterable object.
#### Arguments
1. `iterable` *(`Array` | `Arguments` | `Iterable`)*: An array-like or iterable object to convert to an Observable sequence.
2. `[mapFn]` *(`Function`)*: Map function to call on every element of the array.
3. `[thisArg]` *(`Any`)*: The context to use calling the mapFn if provided.
4. `[scheduler=Rx.Scheduler.currentThread]` *(`Scheduler`)*: Scheduler to run the enumeration of the input sequence on.
#### Returns
*(`Observable`)*: The observable sequence whose elements are pulled from the given iterable sequence.
#### Example
```js
// Array-like object (arguments) to Observable
function f() {
return Rx.Observable.from(arguments);
}
f(1, 2, 3).subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
// Any iterable object...
// Set
var s = new Set(['foo', window]);
Rx.Observable.from(s).subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: foo
// => Next: window
// => Completed
// Map
var m = new Map([[1, 2], [2, 4], [4, 8]]);
Rx.Observable.from(m).subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: [1, 2]
// => Next: [2, 4]
// => Next: [4, 8]
// => Completed
// String
Rx.Observable.from('foo').subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: f
// => Next: o
// => Next: o
// => Completed
// Using an arrow function as the map function to
// manipulate the elements
Rx.Observable.from([1, 2, 3], function (x) { return x + x; }).subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 4
// => Next: 6
// => Completed
// Generate a sequence of numbers
Rx.Observable.from({length: 5}, function(v, k) { return k; }).subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/from.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/from.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/from.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/from.js)
================================================
FILE: doc/api/core/operators/fromarray.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### ** DEPRECATED - Use [Rx.Observable.from](./from.md) instead** `Rx.Observable.fromArray(array, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/fromarray.js "View in source")
Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
#### Arguments
1. `array` *(Array)*: An array to convert to an Observable sequence.
2. `[scheduler=Rx.Scheduler.currentThread]` *(`Scheduler`)*: Scheduler to run the enumeration of the input sequence on.
#### Returns
*(`Observable`)*: The observable sequence whose elements are pulled from the given enumerable sequence.
#### Example
```js
var array = [1,2,3];
var source = Rx.Observable.fromArray(array);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/fromarray.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/fromarray.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/fromarray.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/fromarray.js)
================================================
FILE: doc/api/core/operators/fromcallback.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.fromCallback(func, [context], [selector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/fromcallback.js "View in source")
Converts a callback function to an observable sequence.
#### Arguments
1. `func` *(`Function`)*: Function with a callback as the last parameter to convert to an Observable sequence.
2. `[context]` *(`Any`)*: The context for the func parameter to be executed. If not specified, defaults to undefined.
3. `[selector]` *(`Function`)*: A selector which takes the arguments from the callback to produce a single item to yield on next.
#### Returns
*(`Function`)*: A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array if no selector given, else the object created by the selector function.
#### Example
```js
var fs = require('fs'),
Rx = require('rx');
// Wrap fs.exists
var exists = Rx.Observable.fromCallback(fs.exists);
// Check if file.txt exists
var source = exists('file.txt');
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/fromcallback.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/fromcallback.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/fromcallback.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/fromcallback.js)
================================================
FILE: doc/api/core/operators/fromevent.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.fromEvent(element, eventName, [selector], [options])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromevent.js "View in source")
Creates an observable sequence by adding an event listener to the matching DOMElement, jQuery element, Zepto Element, Angular element, Ember.js element or EventEmitter.
Note that this uses the library approaches for jQuery, Zepto, Backbone.Marionette, AngularJS and Ember.js and falls back to native binding if not present. If you are using AMD you may need to include these libraries as dependencies of RxJs in your requirejs configuration file. RxJs will attempt to detect their presence when deciding which library to use.
#### Arguments
1. `element` *(`Any`)*: The DOMElement, NodeList, jQuery element, Zepto Element, Angular element, Ember.js element or EventEmitter to attach a listener. For Backbone.Marionette this would be the application or an EventAggregator object.
2. `eventName` *(`String`)*: The event name to attach the observable sequence.
3. `[selector]` *(`Function`)*: A selector which takes the arguments from the event emitter so that you can return a single object.
4. `[options]` *( `Object` )* An object of event listener options.
#### Returns
*(`Observable`)*: An observable sequence of events from the specified element and the specified event.
#### Example
Wrapping an event from [jQuery](http://jquery.com)
```js
var input = $('#input');
var source = Rx.Observable.fromEvent(input, 'click');
var subscription = source.subscribe(
function (x) {
console.log('Next: Clicked!');
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
input.trigger('click');
// => Next: Clicked!
```
Using in Node.js with using an `EventEmitter` with a selector function (which is not required).
```js
var EventEmitter = require('events').EventEmitter,
Rx = require('rx');
var eventEmitter = new EventEmitter();
var source = Rx.Observable.fromEvent(
eventEmitter,
'data',
function (foo, bar) { return { foo: foo, bar: bar }; });
var subscription = source.subscribe(
function (x) {
console.log('Next: foo -' + x.foo + ', bar -' + x.bar);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
eventEmitter.emit('data', 'baz', 'quux');
// => Next: foo - baz, bar - quux
```
### Location
File:
- [`/src/core/linq/observable/fromevent.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromevent.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js) | [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/fromevent.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/fromevent.js)
================================================
FILE: doc/api/core/operators/fromeventpattern.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.fromEventPattern(addHandler, [removeHandler], [selector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromeventpattern.js "View in source")
Creates an observable sequence by using the addHandler and removeHandler functions to add and remove the handlers, with an optional selector function to project the event arguments.
#### Arguments
1. `addHandler` *(`Function`)*: The DOMElement, NodeList or EventEmitter to attach a listener.
2. `[removeHandler]` *(`Function`)*: The optional function to remove a handler from an emitter.
3. `[selector]` *(`Function`)*: A selector which takes the arguments from the event handler to produce a single item to yield on next.
#### Returns
*(`Observable`)*: An observable sequence of events from the specified element and the specified event.
#### Example
Wrapping an event from [jQuery](http://jquery.com)
```js
var input = $('#input');
var source = Rx.Observable.fromEventPattern(
function add (h) {
input.bind('click', h);
},
function remove (h) {
input.unbind('click', h);
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: Clicked!');
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
input.trigger('click');
// => Next: Clicked!
```
Wrapping an event from the [Dojo Toolkit](http://dojotoolkit.org)
```js
require(['dojo/on', 'dojo/dom', 'rx', 'rx.async', 'rx.binding'], function (on, dom, rx) {
var input = dom.byId('input');
var source = Rx.Observable.fromEventPattern(
function add (h) {
return on(input, 'click', h);
},
function remove (_, signal) {
signal.remove();
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: Clicked!');
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
on.emit(input, 'click');
// => Next: Clicked!
});
```
Using in Node.js with using an `EventEmitter`.
```js
var EventEmitter = require('events').EventEmitter,
Rx = require('rx');
var e = new EventEmitter();
// Wrap EventEmitter
var source = Rx.Observable.fromEventPattern(
function add (h) {
e.addListener('data', h);
},
function remove (h) {
e.removeListener('data', h);
},
function (foo, bar) {
return foo + ',' + bar;
}
);
var subscription = source.subscribe(
function (result) {
console.log('Next: %s', result);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
e.emit('data', 'foo', 'bar');
// => Next: foo,bar
```
### Location
File:
- [/src/core/linq/observable/fromeventpattern.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/fromeventpattern.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using rx.async.js | rx.async.compat.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx`](https://www.npmjs.org/package/rx).lite.js | rx.lite.compat.js
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/fromeventpattern.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/fromeventpattern.js)
================================================
FILE: doc/api/core/operators/fromnodecallback.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.fromNodeCallback(func, [context], [selector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/fromnodecallback.js "View in source")
Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
#### Arguments
1. `func` *(`Function`)*: Function with a callback as the last parameter to convert to an Observable sequence.
2. `[context]` *(`Any`)*: The context for the func parameter to be executed. If not specified, defaults to undefined.
3. `[selector]` *(`Function`)*: A selector which takes the arguments from callback sans the error to produce a single item to yield on next.
#### Returns
*(`Function`)*: A function which when applied, returns an observable sequence with the callback arguments as an array if no selector given, else the object created by the selector function on success, or an error if the first parameter is not falsy.
#### Example
```js
var fs = require('fs'),
Rx = require('rx');
// Wrap fs.rename
var rename = Rx.Observable.fromNodeCallback(fs.rename);
// Rename file which returns no parameters except an error
var source = rename('file1.txt', 'file2.txt');
var subscription = source.subscribe(
function () {
console.log('Next: success!');
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: success!
// => Completed
```
### Location
File:
- [/src/core/perf/operators/fromnodecallback.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/fromnodecallback.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx`](https://www.npmjs.org/package/rx).lite.js | rx.lite.compat.js
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/fromnodecallback.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/fromnodecallback.js)
================================================
FILE: doc/api/core/operators/frompromise.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.fromPromise(promise)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/frompromise.js "View in source")
Converts a Promises/A+ spec compliant Promise and/or ES2015 compliant Promise or a factory function which returns said Promise to an Observable sequence.
#### Arguments
1. `promise|Function`: `Promise` - Promises/A+ spec compliant Promise to an Observable sequence or a function which returns a Promise.
#### Returns
`Observable`: An Observable sequence which wraps the existing promise success and failure.
#### Example
```js
// Create a factory function which returns a promise
var promiseFn = function () { return Promise.resolve(42); };
var source = Rx.Observable.fromPromise(promiseFn);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// Create a promise which resolves 42
var promise1 = Promise.resolve(42)
var source1 = Rx.Observable.fromPromise(promise1);
var subscription1 = source1.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
// Create a promise which rejects with an error
var promise2 = Promise.reject(new Error('reason'));
var source2 = Rx.Observable.fromPromise(promise2);
var subscription2 = source2.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Error: Error: reject
```
### Location
File:
- [`/src/core/perf/operators/frompromise.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/frompromise.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/frompromise.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/frompromise.js)
================================================
FILE: doc/api/core/operators/generate.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.generate(initialState, condition, iterate, resultSelector, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/generate.js "View in source")
Generates an observable sequence in a manner similar to a for loop, using an optional scheduler to enumerate the values.
#### Arguments
1. `initialState` *(`Any`)*: Initial state.
2. `condition` *(`Function`)*: Condition to terminate generation (upon returning false).
3. `iterate` *(`Function`)*: Iteration step function.
4. `resultSelector` *(`Function`)*: Selector function for results produced in the sequence.
5. `[scheduler=Rx.Scheduler.currentThread]` *(`Scheduler`)*: Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
#### Returns
*(`Observable`)*: The generated sequence.
#### Example
```js
var source = Rx.Observable.generate(
0,
function (x) { return x < 3; },
function (x) { return x + 1; },
function (x) { return x; }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
```
### Location
File:
- [/src/core/linq/observable/generate.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/generate.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/generate.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/generate.js)
================================================
FILE: doc/api/core/operators/generatewithabsolutetime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.generateWithAbsoluteTime(initialState, condition, iterate, resultSelector, timeSelector, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/generatewithabsolutetime.js "View in source")
Generates an observable sequence by iterating a state from an initial state until the condition fails.
#### Arguments
1. `initialState` *(`Any`)*: Initial state.
2. `condition` *(`Function`)*: Condition to terminate generation (upon returning false).
3. `iterate` *(`Function`)*: Iteration step function.
4. `resultSelector` *(`Function`)*: Selector function for results produced in the sequence.
5. `timeSelector` *(`Function`)*: Time selector function to control the speed of values being produced each iteration, returning Date values.
6. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.timeout.
#### Returns
*(`Observable`)*: The generated sequence.
#### Example
```js
// Generate a value with an absolute time with an offset of 100ms multipled by value
var source = Rx.Observable.generate(
1,
function (x) { return x < 4; },
function (x) { return x + 1; },
function (x) { return x; },
function (x) { return Date.now() + (100 * x); }
).timeInterval();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: {value: 1, interval: 100}
// => Next: {value: 2, interval: 200}
// => Next: {value: 3, interval: 300}
// => Completed
```
### Location
File:
- [/src/core/linq/observable/generatewithabsolutetime.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/generatewithabsolutetime.js)
Dist:
- [rx.time.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](https://www.npmjs.org/package/RxJS-All)
- [`RxJS-Time`](https://www.npmjs.org/package/RxJS-Time)
Unit Tests:
- [/tests/observable/generatewithabsolutetime.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/generatewithabsolutetime.js)
================================================
FILE: doc/api/core/operators/generatewithrelativetime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.generateWithRelativeTime(initialState, condition, iterate, resultSelector, timeSelector, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/generatewithrelativetime.js "View in source")
Generates an observable sequence by iterating a state from an initial state until the condition fails.
#### Arguments
1. `initialState` *(`Any`)*: Initial state.
2. `condition` *(`Function`)*: Condition to terminate generation (upon returning false).
3. `iterate` *(`Function`)*: Iteration step function.
4. `resultSelector` *(`Function`)*: Selector function for results produced in the sequence.
5. `timeSelector` *(`Function`)*: Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
6. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.timeout.
#### Returns
*(`Observable`)*: The generated sequence.
#### Example
```js
// Generate a value with an absolute time with an offset of 100ms multipled by value
var source = Rx.Observable.generateWithRelativeTime(
1,
function (x) { return x < 4; },
function (x) { return x + 1; },
function (x) { return x; },
function (x) { return 100 * x; }
).timeInterval();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: {value: 1, interval: 100}
// => Next: {value: 2, interval: 200}
// => Next: {value: 3, interval: 300}
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/generatewithrelativetime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/generatewithrelativetime.js)
Dist:
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- if `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](https://www.npmjs.org/package/RxJS-All)
- [`RxJS-Time`](https://www.npmjs.org/package/RxJS-Time)
Unit Tests:
- [/tests/observable/generatewithrelativetime.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/generatewithrelativetime.js)
================================================
FILE: doc/api/core/operators/groupby.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.groupBy(keySelector, [elementSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/groupby.js "View in source")
Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
#### Arguments
1. `keySelector` *(`Function`)*: A function to extract the key for each element.
2. `[elementSelector]` *(`Function`)*: A function to map each source element to an element in an observable group.
#### Returns
*(`Observable`)*: A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
#### Example
```js
var codes = [
{ keyCode: 38}, // up
{ keyCode: 38}, // up
{ keyCode: 40}, // down
{ keyCode: 40}, // down
{ keyCode: 37}, // left
{ keyCode: 39}, // right
{ keyCode: 37}, // left
{ keyCode: 39}, // right
{ keyCode: 66}, // b
{ keyCode: 65} // a
];
var source = Rx.Observable.from(codes)
.groupBy(
function (x) { return x.keyCode; },
function (x) { return x.keyCode; });
var subscription = source.subscribe(
function (obs) {
// Print the count
obs.count().subscribe(function (x) {
console.log('Count: ' + x);
});
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Count: 2
// => Count: 2
// => Count: 2
// => Count: 2
// => Count: 1
// => Count: 1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/groupby.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/groupby.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/groupby.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/groupby.js)
================================================
FILE: doc/api/core/operators/groupbyuntil.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.groupByUntil(keySelector, [elementSelector], durationSelector)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/groupbyuntil.js "View in source")
Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
#### Arguments
1. `keySelector` *(`Function`)*: A function to extract the key for each element.
2. `[elementSelector]` *(`Function`)*: A function to map each source element to an element in an observable group.
3. `durationSelector` *(`Function`)*: A function to signal the expiration of a group.
#### Returns
*(`Observable`)*: A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encountered.
#### Example
```js
var codes = [
{ keyCode: 38}, // up
{ keyCode: 38}, // up
{ keyCode: 40}, // down
{ keyCode: 40}, // down
{ keyCode: 37}, // left
{ keyCode: 39}, // right
{ keyCode: 37}, // left
{ keyCode: 39}, // right
{ keyCode: 66}, // b
{ keyCode: 65} // a
];
var source = Rx.Observable
.for(codes, function (x) { return Rx.Observable.return(x).delay(1000); })
.groupByUntil(
function (x) { return x.keyCode; },
function (x) { return x.keyCode; },
function (x) { return Rx.Observable.timer(2000); });
var subscription = source.subscribe(
function (obs) {
// Print the count
obs.count().subscribe(function (x) { console.log('Count: ' + x); });
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Count: 2
// => Count: 2
// => Count: 1
// => Count: 1
// => Count: 1
// => Count: 1
// => Count: 1
// => Count: 1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/groupbyuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/groupbyuntil.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/groupbyuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/groupbyuntil.js)
================================================
FILE: doc/api/core/operators/groupjoin.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.groupJoin(right, leftDurationSelector, rightDurationSelector, resultSelector)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/groupjoin.js "View in source")
Correlates the elements of two sequences based on overlapping durations, and groups the results.
#### Arguments
1. `right` *(`Observable`)*: The right observable sequence to join elements for.
2. `leftDurationSelector` *(`Function`)*: A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
3. `rightDurationSelector` *(`Function`)*: A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
4. `resultSelector` *(`Any`)*: A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence. It has the following arguments
1. *(`Any`)* An element of the left sequence.
2. *(`Observable`)* An observable sequence with elements from the right sequence that overlap with the left sequence's element.
#### Returns
*(`Observable`)*: An observable sequence that contains result elements computed from source elements that have an overlapping duration.
#### Example
```js
var xs = Rx.Observable.interval(100)
.map(function (x) { return 'first' + x; });
var ys = Rx.Observable.interval(100)
.map(function (x) { return 'second' + x; });
var source = xs.groupJoin(
ys,
function () { return Rx.Observable.timer(0); },
function () { return Rx.Observable.timer(0); },
function (x, yy) {
return yy.select(function (y) {
return x + y;
})
}).mergeAll().take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: first0second0
// => Next: first1second1
// => Next: first2second2
// => Next: first3second3
// => Next: first4second4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/groupjoin.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/groupjoin.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/groupjoin.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/groupjoin.js)
================================================
FILE: doc/api/core/operators/if.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.if(condition, thenSource, [elseSource])`
### `Rx.Observable.ifThen(condition, thenSource, [elseSource])` *DEPRECATED*
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/if.js "View in source")
Determines whether an observable collection contains values. There is an alias for this method called `ifThen` for browsers Next: 42
// => Completed
// The next example uses an elseSource
var shouldRun = false;
var source = Rx.Observable.if(
function () { return shouldRun; },
Rx.Observable.return(42),
Rx.Observable.return(56)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 56
// => Completed
```
### Location
File:
- [/src/core/linq/observable/if.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/if.js)
Dist:
- [rx.all.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [rx.experimental.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- If using `rx.experimental.js` - [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [/tests/observable/if.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/if.js)
================================================
FILE: doc/api/core/operators/ignoreelements.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.ignoreElements()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/ignoreelements.js "View in source")
Ignores all elements in an observable sequence leaving only the termination messages.
#### Returns
*(`Observable`)*: An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
#### Example
```js
var source = Rx.Observable.range(0, 10)
.ignoreElements();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/ignoreelements.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/ignoreelements.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/ignoreelements.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/ignoreelements.js)
================================================
FILE: doc/api/core/operators/includes.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.includes(searchElement, [fromIndex])` ###
### `Rx.Observable.prototype.contains(searchElement, [fromIndex])` **DEPRECATED** ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/includes.js "View in source")
Determines whether an observable sequence includes a specified element with an optional from index.
#### Arguments
1. `searchElement` *(`Any`)*: The value to locate in the source sequence.
2. `[fromIndex]` *(`Number`)*: The index to start the search. If not specified, defaults to 0.
#### Returns
*(`Observable`)*: An observable sequence containing a single element determining whether the source sequence includes an element that has the specified value with an optional from index.
#### Example
```js
/* Without an index */
var source = Rx.Observable.of(42)
.includes(42);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
/* With an index */
var source = Rx.Observable.of(1,2,3)
.includes(2, 1);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/includes.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/includes.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/includes.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/includes.js)
================================================
FILE: doc/api/core/operators/indexof.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.indexOf(searchElement, [fromIndex])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/indexof.js "View in source")
Returns the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
#### Arguments
1. `searchElement` *(`Any`)*: The value to locate in the source sequence.
2. `[fromIndex]` *(`Number`)*: The index to start the search. If not specified, defaults to 0.
#### Returns
*(`Observable`)*: And observable sequence containing the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
#### Example
```js
/* Without an index */
var source = Rx.Observable.of(42)
.indexOf(42);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Completed
/* With an index */
var source = Rx.Observable.of(1,2,3)
.indexOf(2, 1);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/indexof.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/indexof.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/indexof.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/indexof.js)
================================================
FILE: doc/api/core/operators/interval.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.interval(period, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/interval.js "View in source")
Returns an observable sequence that produces a value after each period.
#### Arguments
1. `period` *(`Number`)*: Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
2. `[scheduler]` *(Scheduler=Rx.Scheduler.timeout)*: Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
#### Returns
*(`Observable`)*: An observable sequence that produces a value after each period. Each value produced will default to a `Number` denoting its order in the timeline. (e.g. `0, 1, 2...`)
#### Example
```js
var source = Rx.Observable
.interval(500 /* ms */)
.timeInterval()
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: {value: 0, interval: 500}
// => Next: {value: 1, interval: 500}
// => Next: {value: 2, interval: 500}
// => Completed
```
### Location
File:
- [/src/core/linq/observable/interval.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/interval.js)
Dist:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- if `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](https://www.npmjs.org/package/RxJS-Time)
- [`RxJS-Time`](https://www.npmjs.org/package/RxJS-Time)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/interval.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/interval.js)
================================================
FILE: doc/api/core/operators/isempty.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.isEmpty()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/isempty.js "View in source")
Determines whether an observable sequence is empty.
#### Returns
*(`Observable`)*: An observable sequence containing a single element determining whether the source sequence is empty.
#### Example
```js
/* Not empty */
var source = Rx.Observable.range(0, 5)
.isEmpty()
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: false
// => Completed
/* Empty */
var source = Rx.Observable.empty()
.isEmpty()
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/isempty.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/isempty.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/isempty.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/isempty.js)
================================================
FILE: doc/api/core/operators/join.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.join(right, leftDurationSelector, rightDurationSelector, resultSelector)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/join.js "View in source")
Correlates the elements of two sequences based on overlapping durations.
#### Arguments
1. `right` *(`Observable`)*: The right observable sequence to join elements for.
2. `leftDurationSelector` *(`Function`)*: A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
3. `rightDurationSelector` *(`Function`)*: A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
4. `resultSelector` *(`Any`)*: A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences. The parameters are as follows:
1. *(`Any`)* Element from the left source for which the overlap occurs.
2. *(`Any`)* Element from the right source for which the overlap occurs.
#### Returns
*(`Observable`)*: An observable sequence that contains result elements computed from source elements that have an overlapping duration.
#### Example
```js
var xs = Rx.Observable.interval(100)
.map(function (x) { return 'first' + x; });
var ys = Rx.Observable.interval(100)
.map(function (x) { return 'second' + x; });
var source = xs
.join(
ys,
function () { return Rx.Observable.timer(0); },
function () { return Rx.Observable.timer(0); },
function (x, y) { return x + y; }
)
.take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: first0second0
// => Next: first1second1
// => Next: first2second2
// => Next: first3second3
// => Next: first4second4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/join.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/join.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/join.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/join.js)
================================================
FILE: doc/api/core/operators/jortsort.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.jortSort()` [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/jortsort.js "View in source")
The `jortSort` method checks if your inputs are sorted. Note that this is only for a sequence with an end.
See [http://jort.technology/](http://jort.technology/) for full details.
#### Returns
*(`Observable`)*: An observable which has a single value of `true` if sorted, else `false`.
#### Example
```js
// Sorted
var source = Rx.Observable.of(1,2,3,4)
.jortSort();
var subscription = source.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function ( ) { console.log('Completed'); }
);
// => Next: true
// => Completed
// Non sorted
var source = Rx.Observable.of(3,1,2,4)
.jortSort();
var subscription = source.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function ( ) { console.log('Completed'); }
);
// => Next: false
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/jortsort.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/jortsort.js)
Dist:
- [`rx.sorting.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.sorting.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Unit Tests:
- [`/tests/observable/jortsort.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/jortsort.js)
================================================
FILE: doc/api/core/operators/jortsortuntil.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.jortSortUntil(other)` [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/jortsortuntil.js "View in source")
The `jortSort` method checks if your inputs are sorted until another Observable sequence fires.
See [http://jort.technology/](http://jort.technology/) for full details.
#### Arguments
1. `other` *(`Observable`)*: The Observable sequence which will cause the termination of the sequence.
#### Returns
*(`Observable`)*: An observable which has a single value of `true` if sorted, else `false`.
#### Example
```js
var just = Rx.helpers.just;
// Sorted
var source = Rx.Observable.of(1,2,3,4)
.flatMap(function (x) {
return Rx.Observable.timer(1000).map(just(x));
})
.jortSortUntil(Rx.Observable.timer(3000));
var subscription = source.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function ( ) { console.log('Completed'); }
);
// => Next: true
// => Completed
// Non sorted
var source = Rx.Observable.of(3,1,2,4)
.flatMap(function (x) {
return Rx.Observable.timer(1000).map(just(x));
})
.jortSortUntil(Rx.Observable.timer(3000));
var subscription = source.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function ( ) { console.log('Completed'); }
);
// => Next: false
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/jortsortuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/jortsortuntil.js)
Dist:
- [`rx.sorting.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.sorting.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Unit Tests:
- [`/tests/observable/jortsortuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/jortsortuntil.js)
================================================
FILE: doc/api/core/operators/last.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.last([predicate], [thisArg])`
### `Rx.Observable.prototype.last([settings])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/last.js "View in source")
Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element. If no element was found and no default value is specified, `onError` is called with an error, however if a default value was specified, it will be yielded via an `onNext` call.
#### Arguments
`Rx.Observable.prototype.last([predicate], [thisArg], [defaultValue])`
1. `[predicate]` *(`Function`)*: A predicate function to evaluate for elements in the source sequence. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
3. `[defaultValue]` *(`Any`)*: Default value if no such element exists.
`Rx.Observable.prototype.last([settings])`
1. `[settings]` *(`Object`)*: An object with the following fields
- `[predicate]` *(`Function`)*: A predicate function to evaluate for elements in the source sequence. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
- `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
- `[defaultValue]` *(`Any`)*: Default value if no such element exists.
#### Returns
*(`Observable`)*: Sequence containing the last element in the observable sequence that satisfies the condition.
#### Example
```js
/* Default value */
var source = Rx.Observable.empty().last({defaultValue: 42});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
/* Without predicate */
var source = Rx.Observable.range(0, 10).last();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 9
// => Completed
/* With predicate */
var source = Rx.Observable.range(0, 10)
.last(function (x, idx, obs) {
return x % 2 === 0;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 8
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/last.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/last.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/last.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/last.js)
================================================
FILE: doc/api/core/operators/lastindexof.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.lastIndexOf(searchElement, [fromIndex])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/lastindexof.js "View in source")
Returns the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
#### Arguments
1. `searchElement` *(`Any`)*: The value to locate in the source sequence.
2. `[fromIndex]` *(`Number`)*: The index to start the search. If not specified, defaults to 0.
#### Returns
*(`Observable`)*: And observable sequence containing the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
#### Example
```js
/* Without an index */
var source = Rx.Observable.of(1,2,3,1,2,3)
.lastIndexOf(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 5
// => Completed
/* With an index */
var source = Rx.Observable.of(1,2,3,1,2,3)
.lastIndexOf(2, 1);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 5
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/lastindexof.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/lastindexof.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/lastindexof.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/lastindexof.js)
================================================
FILE: doc/api/core/operators/let.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.let(func)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/let.js "View in source")
Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions.
This operator allows for a fluent style of writing queries that use the same sequence multiple times. There is an alias of `letBind` for browsers older than IE 9.
#### Arguments
1. `func` *(`Function`)*: Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
#### Example
```js
var obs = Rx.Observable.range(1, 3);
var source = obs.let(function (o) { return o.concat(o); });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/let.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/let.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/let.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/let.js)
================================================
FILE: doc/api/core/operators/manyselect.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.manySelect(selector, [scheduler])`
### `Rx.Observable.prototype.extend(selector, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/manyselect.js "View in source")
Comonadic bind operator.
#### Arguments
1. `selector` *(`Function`)*: A transform function to apply to each element.
2. `[scheduler=Rx.Scheduler.immediate]` *(`Scheduler`)*: Scheduler used to execute the operation. If not specified, defaults to the `Rx.Scheduler.immediate` scheduler.
#### Returns
*(`Observable`)*: An observable sequence which results from the comonadic bind operation.
#### Example
```js
var source = Rx.Observable.range(0, 3)
.manySelect(function (ys) { return ys.first(); })
.mergeAll();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/manyselect.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/manyselect.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/manyselect.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/manyselect.js)
================================================
FILE: doc/api/core/operators/materialize.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.materialize()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/materialize.js "View in source")
Materializes the implicit notifications of an observable sequence as explicit notification values.
#### Returns
*(`Observable`)*: An observable sequence containing the materialized notification values from the source sequence.
#### Example
```js
var source = Rx.Observable.of(1,2,3).materialize();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next OnNext(1)
// => Next OnNext(2)
// => Next OnNext(3)
// => Next OnCompleted()
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/materialize.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/materialize.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/materialize.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/materialize.js)
================================================
FILE: doc/api/core/operators/max.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.max([comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/max.js "View in source")
Returns the maximum value in an observable sequence according to the specified comparer.
#### Arguments
1. `[comparer]` *(`Function`)*: Comparer used to compare elements.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with the maximum element in the source sequence.
#### Example
```js
/* Without comparer */
var source = Rx.Observable.from([1,3,5,7,9,2,4,6,8])
.max();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 9
// => Completed
/* With a comparer */
function comparer (x, y) {
if (x > y) {
return 1;
} else if (x < y) {
return -1;
}
return 0;
}
var source = Rx.Observable.from([1,3,5,7,9,2,4,6,8])
.max(comparer);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 9
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/max.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/max.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/max.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/max.js)
================================================
FILE: doc/api/core/operators/maxby.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.maxBy(keySelector, [comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/maxby.js "View in source")
Returns the maximum value in an observable sequence according to the specified comparer.
#### Arguments
1. `keySelector` *(`Function`)*: Key selector function.
2. `[comparer]` *(`Function`)*: Comparer used to compare elements.
#### Returns
*(`Observable`)*: An observable sequence containing a list of zero or more elements that have a maximum key value.
#### Example
```js
/* Without comparer */
var source = Rx.Observable.from([1,3,5,7,9,2,4,6,8,9])
.maxBy(function (x) { return x; });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 9,9
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/maxby.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/maxby.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/maxby.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/maxby.js)
================================================
FILE: doc/api/core/operators/merge.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.merge([scheduler], ...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/merge.js "View in source")
Merges all the observable sequences and Promises into a single observable sequence.
#### Arguments
1. `[scheduler]` *(Scheduler=Rx.Scheduler.immediate)*: Scheduler to run the timer on. If not specified, Rx.Scheduler.immediate is used.
1. `args` *(Array|arguments)*: Observable sequences to merge into a single sequence.
#### Returns
*(`Observable`)*: An observable sequence that produces a value after each period.
#### Example
```js
var source1 = Rx.Observable.interval(100)
.timeInterval()
.pluck('interval');
var source2 = Rx.Observable.interval(150)
.timeInterval()
.pluck('interval');
var source = Rx.Observable.merge(
source1,
source2)
.take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 100
// => Next: 150
// => Next: 100
// => Next: 150
// => Next: 100
// => Completed
```
### Location
File:
- [/src/core/linq/observable/merge.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/merge.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/merge.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/merge.js)
================================================
FILE: doc/api/core/operators/mergeall.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.mergeAll()` ###
### `Rx.Observable.prototype.mergeObservable()` **DEPRECATED** ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/mergeall.js "View in source")
Merges an observable sequence of observable sequences into an observable sequence.
#### Returns
*(`Observable`)*: The observable sequence that merges the elements of the inner sequences.
#### Example
```js
var source = Rx.Observable.range(0, 3)
.map(function (x) { return Rx.Observable.range(x, 3); })
.mergeAll();
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 1
// => Next: 2
// => Next: 2
// => Next: 2
// => Next: 3
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/modular/observable/mergeall.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/modular/observable/mergeall.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/mergeall.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/mergeall.js)
================================================
FILE: doc/api/core/operators/mergedelayerror.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.mergeDelayError(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/mergedelayerror.js "View in source")
Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
receive all successfully emitted items from all of the source Observables without being interrupted by
an error notification from one of them.
This behaves like `Observable.prototype.mergeAll` except that if any of the merged Observables notify of an
error via the Observer's `onError`, `mergeDelayError` will refrain from propagating that
error notification until all of the merged Observables have finished emitting items.
#### Arguments
1. `args` *(Array|arguments)*: Arguments or an array of Observable sequences to merge.
#### Returns
*(`Observable`)*: An Observable that emits all of the items emitted by the Observables emitted by the Observable
#### Example
```js
var source1 = Rx.Observable.of(1,2,3);
var source2 = Rx.Observable.throwError(new Error('woops'));
var source3 = Rx.Observable.of(4,5,6);
var source = Rx.Observable.mergeDelayError(source1, source2, source3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => 1
// => 2
// => 3
// => 4
// => 5
// => 6
// => Error: Error: woops
```
### Location
File:
- [/src/core/linq/observable/mergedelayerror.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/mergedelayerror.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/mergedelayerror.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/mergedelayerror.js)
================================================
FILE: doc/api/core/operators/mergeproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.merge(maxConcurrent | other)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/mergeconcat.js "View in source")
Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
Or merges two observable sequences into a single observable sequence.
#### Arguments
1. `maxConcurrent` *(`Number`)*: Maximum number of inner observable sequences being subscribed to concurrently.
1. `other` *(`Observable`)*: The second observable sequence to merge into the first.
#### Returns
*(`Observable`)*: The observable sequence that merges the elements of the inner sequences.
#### Example
```js
/* Merge two sequences */
var source1 = Rx.Observable.interval(100)
.map(function (x) { return 'First: ' + x; });
var source2 = Rx.Observable.interval(50)
.map(function (x) { return 'Second: ' + x; });
var source = source1
.merge(source2)
.take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: Second: 0
// => Next: First: 0
// => Next: Second: 1
// => Next: Second: 2
// => Next: First: 1
// => Completed
/* Use max concurrency */
var source = Rx.Observable.range(0, 3)
.map(function (x) { return Rx.Observable.range(x, 3); })
.merge(1);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/mergeconcat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/mergeconcat.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/mergeconcat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/mergeconcat.js)
* * *
================================================
FILE: doc/api/core/operators/min.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.min([comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/min.js "View in source")
Returns the minimum element in an observable sequence according to the optional comparer else a default greater than less than check.
#### Arguments
1. `[comparer]` *(`Function`)*: Comparer used to compare elements.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with the minimum element in the source sequence.
#### Example
```js
/* Without comparer */
var source = Rx.Observable.from([1,3,5,7,9,2,4,6,8])
.min();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Completed
/* With a comparer */
function comparer (x, y) {
if (x > y) {
return 1;
} else if (x < y) {
return -1;
}
return 0;
}
var source = Rx.Observable.from([1,3,5,7,9,2,4,6,8])
.min(comparer);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/min.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/min.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/min.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/min.js)
================================================
FILE: doc/api/core/operators/minby.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.minBy(keySelector, [comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/minby.js "View in source")
Returns the elements in an observable sequence with the minimum key value according to the specified comparer.
#### Arguments
1. `keySelector` *(`Function`)*: Key selector function.
2. `[comparer]` *(`Function`)*: Comparer used to compare elements.
#### Returns
*(`Observable`)*: An observable sequence containing a list of zero or more elements that have a minimum key value.
#### Example
```js
/* Without comparer */
var source = Rx.Observable.from([1,3,5,7,9,2,4,6,8,1])
.minBy(function (x) { return x; });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1,1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/minby.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/minby.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/minby.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/minby.js)
================================================
FILE: doc/api/core/operators/multicast.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.multicast(subject | subjectSelector, [selector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/multicast.js "View in source")
Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
invocation. For specializations with fixed subject types, see `publish`, `share`, `publishValue`, `shareValue`, `publishLast`, `replay`, and `shareReplay`.
#### Arguments
1. `subjectSelector` *(`Function`)*: Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
1. `subject` *(Subject)*: Subject to push source elements into.
2. `[selector]` *(`Function`)*: Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if `subjectSelector` is provided.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
#### Example
```js
var subject = new Rx.Subject();
var source = Rx.Observable.range(0, 3)
.multicast(subject);
var observer = Rx.Observer.create(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
}
);
var subscription = source.subscribe(observer);
subject.subscribe(observer);
var connected = source.connect();
subscription.dispose();
// => Next: 0
// => Next: 0
// => Next: 1
// => Next: 1
// => Next: 2
// => Next: 2
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/multicast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/multicast.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/multicast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/multicast.js)
================================================
FILE: doc/api/core/operators/never.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.never()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/never.js "View in source")
Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
#### Returns
*(`Observable`)*: An observable sequence whose observers will never get called.
#### Example
```js
// This will never produce a value, hence never calling any of the callbacks
var source = Rx.Observable.never();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
```
### Location
File:
- [/src/core/perf/operators/never.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/never.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/never.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/never.js)
================================================
FILE: doc/api/core/operators/observeon.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.observeOn(scheduler)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/observeon.js "View in source")
Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects that require to be run on a scheduler, use subscribeOn.
#### Arguments
1. `scheduler` *(`Scheduler`)*: Scheduler to notify observers on.
#### Returns
*(`Observable`)*: The source sequence whose observations happen on the specified scheduler.
#### Example
```js
/* Change from immediate scheduler to timeout */
var source = Rx.Observable.return(42, Rx.Scheduler.immediate)
.observeOn(Rx.Scheduler.timeout);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/observeon.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/observeon.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
- [`rx.lite.extras.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/observeon.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/observeon.js)
================================================
FILE: doc/api/core/operators/of.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.of(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/of.js "View in source")
Converts arguments to an observable sequence.
#### Arguments
1. `args` *(Arguments)*: A list of arguments to turn into an Observable sequence.
#### Returns
*(`Observable`)*: The observable sequence whose elements are pulled from the given arguments.
#### Example
```js
var source = Rx.Observable.of(1,2,3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/of.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/of.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/of.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/of.js)
* * *
================================================
FILE: doc/api/core/operators/ofarraychanges.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.ofArrayChanges(array)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/ofarraychanges.js "View in source")
Creates an Observable sequence from changes to an array using `Array.observe`.
#### Arguments
1. `array` *(`Array`)*: The array to observe changes using `Array.observe`
#### Returns
*(`Observable`)*: An observable sequence containing changes to an array from `Array.observe`.
#### Example
```js
var arr = [1,2,3];
var source = Rx.Observable.ofArrayChanges(arr);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
arr.push(4);
// => Next: {type: "splice", object: Array[4], index: 3, removed: Array[0], addedCount: 1}
```
### Location
File:
- [`/src/core/linq/observable/ofarraychanges.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/ofarraychanges.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
Prerequisites:
- None
NPM Packages:
- None
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
Unit Tests:
- [`/tests/observable/ofarraychanges.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/ofarraychanges.js)
================================================
FILE: doc/api/core/operators/ofobjectchanges.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.ofObjectChanges(obj)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/ofobjectchanges.js "View in source")
Creates an Observable sequence from changes to an object using `Object.observe`.
#### Arguments
1. `array` *(`Array`)*: The object to observe changes using `Object.observe`
#### Returns
*(`Observable`)*: An observable sequence containing changes to an object from `Object.observe`.
#### Example
```js
var obj = {x: 1};
var source = Rx.Observable.ofObjectChanges(obj);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
obj.x = 42;
// => Next: {type: "update", object: Object, name: "x", oldValue: 1}
```
### Location
File:
- [`/src/core/linq/observable/ofobjectchanges.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/ofobjectchanges.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
Prerequisites:
- None
NPM Packages:
- None
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
Unit Tests:
- [`/tests/observable/ofarraychanges.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/ofobjectchanges.js)
================================================
FILE: doc/api/core/operators/ofwithscheduler.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.ofWithScheduler([scheduler], ...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/of.js "View in source")
Converts arguments to an observable sequence, using an optional scheduler to enumerate the arguments.
#### Arguments
1. `[scheduler]` *(Scheduler)*: An optional scheduler used to enumerate the arguments.
2. `args` *(Arguments)*: A list of arguments to turn into an Observable sequence.
#### Returns
*(`Observable`)*: The observable sequence whose elements are pulled from the given arguments.
#### Example
```js
var source = Rx.Observable.ofWithScheduler(Rx.Scheduler.timeout, 1,2,3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/of.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/of.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/of.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/of.js)
================================================
FILE: doc/api/core/operators/onerrorresumenext.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.onErrorResumeNext(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/onerrorresumenext.js "View in source")
Continues an observable sequence that is terminated normally or by an exception with the next observable sequence or Promise.
### Arguments
1. `args` *(Array|arguments)*: Observable sequences to concatenate.
#### Returns
*(`Observable`)*: An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
#### Example
```js
var source1 = Rx.Observable.throw(new Error('error 1'));
var source2 = Rx.Observable.throw(new Error('error 2'));
var source3 = Rx.Observable.return(42);
var source = Rx.Observable.onErrorResumeNext(source1, source2, source3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [/src/core/linq/observable/onerrorresumenext.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/onerrorresumenext.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [/tests/observable/onerrorresumenext.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/onerrorresumenext.js)
================================================
FILE: doc/api/core/operators/onerrorresumenextproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.onErrorResumeNext(second)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/onerrorresumenextproto.js "View in source")
Continues an observable sequence that is terminated normally or by an exception with the next observable sequence or Promise.
#### Arguments
1. `second` *(`Observable` | `Promise`)*: Second observable sequence used to produce results after the first sequence terminates.
#### Returns
*(`Observable`)*: An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
#### Example
```js
var source = Rx.Observable.throw(new Error())
.onErrorResumeNext(Rx.Observable.return(42));
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/onerrorresumenextproto.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/onerrorresumenextproto.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/onerrorresumenext.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/onerrorresumenext.js)
================================================
FILE: doc/api/core/operators/pairs.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.pairs(obj, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/pairs.js "View in source")
Convert an object into an observable sequence of [key, value] pairs using an optional `Scheduler` to enumerate the object.
#### Arguments
1. `obj` *(Object)*: The object to inspect and turn into an Observable sequence.
2. `[scheduler]` *(`Scheduler`)*: Scheduler to run the enumeration of the input sequence on. If not specified, defaults to `Rx.Scheduler.currentThread`
#### Returns
*(`Observable`)*: An observable sequence of [key, value] pairs from the object.
#### Example
```js
// Using Standard JavaScript
var obj = {
foo: 42,
bar: 56,
baz: 78
};
var source = Rx.Observable.pairs(obj);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: ['foo', 42]
// => Next: ['bar', 56]
// => Next: ['baz', 78]
// => Completed
```
ES6 makes for an even nicer experience such as:
```es6
let obj = {
foo: 42,
bar: 56,
baz: 78
};
let source = Rx.Observable.pairs(obj);
let subscription = source.subscribe(
x => {
var [key, value] = x;
console.log('Key:', key, 'Value:', value);
},
err => {
console.log('Error: %s', err);
},
=> () {
console.log('Completed');
});
// => Key: 'foo' Value: 42
// => Key: 'bar' Value: 56
// => Key: 'baz' Value: 78
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/pairs.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/pairs.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/pairs.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/pairs.js)
================================================
FILE: doc/api/core/operators/pairwise.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.pairwise()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/pairwise.js "View in source")
Triggers on the second and subsequent triggerings of the input observable. The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair.
#### Returns
*(`Observable`)*: An observable that triggers on successive pairs of observations from the input observable as an array.
#### Example
```js
var r = Rx.Observable.range(1, 4);
var source = r.pairwise();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + JSON.stringify(x));
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: [1,2]
// => Next: [2,3]
// => Next: [3,4]
// => Completed
```
#### Example (Draw line)
```html
```
```js
var canvas = document.getElementById("canvas");
var g = canvas.getContext("2d");
g.rect(0, 0, canvas.width, canvas.height);
g.fillStyle = "rgb(0,0,0)";
g.fill();
var mouseMove = Rx.Observable.fromEvent(document, 'mousemove');
var mouseDown = Rx.Observable.fromEvent(document.getElementById('canvas'), 'mousedown');
var mouseUp = Rx.Observable.fromEvent(document.getElementById('canvas'), 'mouseup');
mouseDown.flatMap(function(ev) {
return mouseMove.map(function(ev) {
return {
x: ev.clientX,
y: ev.clientY
};
}).pairwise().takeUntil(mouseUp);
}).subscribe(function(pos) {
g.beginPath();
g.lineWidth = 1;
g.strokeStyle = "rgb(255, 0, 0)";
g.moveTo(pos[0].x, pos[0].y);
g.lineTo(pos[1].x, pos[1].y);
g.stroke();
});
```
### Location
File:
- [`/src/core/linq/observable/pairwise.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/pairwise.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/pairwise.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/pairwise.js)
================================================
FILE: doc/api/core/operators/partition.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.partition(predicate, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/partition.js "View in source")
Returns two observables which partition the observations of the source by the given function. The first will trigger observations for those values for which the predicate returns true. The second will trigger observations for those values where the predicate returns false. The predicate is executed once for each subscribed observer. Both also propagate all error observations arising from the source and each completes when the source completes.
#### Arguments
1. `predicate` *(`Function`)*: Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Array`)*: An array of observables. The first triggers when the predicate returns true, and the second triggers when the predicate returns false.
#### Example
An example using ES6 syntax:
```es6
let [evens, odds] = Rx.Observable.range(0, 10)
.partition(x => x % 2 === 0);
let subscription1 = evens.subscribe(
x => console.log('Evens: %s', x),
e => console.log('Error: %s', e),
() => console.log('Completed')
);
// => Evens: 0
// => Evens: 2
// => Evens: 4
// => Evens: 6
// => Evens: 8
// => Completed
let subscription2 = odds.subscribe(
x => console.log('Odds: %s', x),
e => console.log('Error: %s', e),
() => console.log('Completed')
);
// => Odds: 1
// => Odds: 3
// => Odds: 5
// => Odds: 7
// => Odds: 9
// => Completed
```
#### Example
```html
```
```js
var sourceElement = document.getElementById("dom-event-source");
var elements = ["#dom-event-output .left p", "#dom-event-output .right p"].map(document.querySelector.bind(document));
var elementRect = sourceElement.getBoundingClientRect();
var observers = Rx.Observable.fromEvent(sourceElement, 'mousemove')
.map(e => ({
x: Math.floor(e.clientX - elementRect.left),
y: Math.floor(e.clientY - elementRect.top)
})
).partition(pos => pos.x < sourceElement.clientWidth / 2);
elements.forEach((n, i, a) =>
observers[i].subscribe(displayCoordinates.bind(displayCoordinates, n)));
function displayCoordinates(element, pos) {
element.textContent = `(x: ${pos.x}, y: ${pos.y})`;
}
```
### Location
File:
- [`/src/core/linq/observable/partition.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/partition.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/partition.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/partition.js)
================================================
FILE: doc/api/core/operators/pausable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.pausable(pauser)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/backpressure/pausable.js "View in source")
Pauses the underlying observable sequence based upon the observable sequence which yields true/false. Note that this only works on hot observables.
#### Arguments
1. `pauser` *(`Observable`)*: The observable sequence used to pause the underlying sequence.
#### Returns
*(`Observable`)*: The observable sequence which is paused based upon the pauser.
#### Example
```js
var pauser = new Rx.Subject();
var source = Rx.Observable.fromEvent(document, 'mousemove').pausable(pauser);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// To begin the flow
pauser.onNext(true); // or source.resume();
// To pause the flow at any point
pauser.onNext(false); // or source.pause();
```
### Location
File:
- [`/src/core/backpressure/pausable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/backpressure/pausable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [rx.backpressure.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.backpressure.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.backpressure.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-BackPressure`](http://www.nuget.org/packages/RxJS-BackPressure/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/pausable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/pausable.js)
================================================
FILE: doc/api/core/operators/pausablebuffered.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.pausableBuffered(pauser)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/backpressure/pausablebuffered.js "View in source")
Pauses the underlying observable sequence based upon the observable sequence which yields true/false, and yields the values that were buffered while paused. Note that this only works on hot observables.
#### Arguments
1. `pauser` *(`Observable`)*: The observable sequence used to pause the underlying sequence.
#### Returns
*(`Observable`)*: The observable sequence which is paused based upon the pauser.
#### Example
```js
var pauser = new Rx.Subject();
var source = Rx.Observable.interval(1000).pausableBuffered(pauser);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// To begin the flow
pauser.onNext(true); // or source.resume();
// To pause the flow at any point
pauser.onNext(false); // or source.pause();
// Resume the flow which empties the queue from when you last paused
pauser.onNext(true); // or source.resume();
```
### Location
File:
- [`/src/core/backpressure/pausablebuffered.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/backpressure/pausablebuffered.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [rx.backpressure.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.backpressure.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.backpressure.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-BackPressure`](http://www.nuget.org/packages/RxJS-BackPressure/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/pausablebuffered.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/pausablebuffered.js)
================================================
FILE: doc/api/core/operators/pluck.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.pluck(property)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/pluck.js#L10 "View in source")
Returns an Observable containing the value of a specified nested property from
all elements in the Observable sequence. If a property can't be resolved, it
will return `undefined` for that value.
#### Arguments
1. `property` *(`String`)*: The property or properties to pluck. `pluck`
accepts an unlimited number of nested property parameters.
#### Returns
*(`Observable`)*: Returns a new Observable sequence of property values.
#### Example
```js
var source = Rx.Observable
.from([
{ value: 0 },
{ value: 1 },
{ value: 2 }
])
.pluck('value');
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
// Using nested properties:
var source = Rx.Observable
.from([
{ valueA: { valueB: { valueC: 0 }}},
{ valueA: { valueB: { valueC: 1 }}},
{ valueA: { valueB: 2 }},
])
.pluck('valueA', 'valueB', 'valueC');
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: undefined
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/pluck.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/pluck.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/pluck.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/pluck.js)
================================================
FILE: doc/api/core/operators/publish.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.publish([selector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/publish.js "View in source")
Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence.
This operator is a specialization of `multicast` using a regular `Rx.Subject`.
#### Arguments
1. `[selector]` *(`Function`)*: Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all notifications of the source from the time of the subscription on.
#### Returns
*(ConnectableObservable)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
#### Example
```js
/* Without publish */
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.do(function (x) {
console.log('Side effect');
});
source.subscribe(createObserver('SourceA'));
source.subscribe(createObserver('SourceB'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Side effect
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Completed
// => Side effect
// => Next: SourceB1
// => Completed
/* With publish */
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.doAction(function (x) {
console.log('Side effect');
});
var published = source.publish();
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
var connection = published.connect();
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/publish.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/publish.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/publish.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/publish.js)
================================================
FILE: doc/api/core/operators/publishlast.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.publishLast([selector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/publishlast.js "View in source")
Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence containing only the last notification.
This operator is a specialization of `multicast` using a `Rx.AsyncSubject`.
#### Arguments
1. `[selector]` *(`Function`)*: Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will only receive the last notification of the source.
#### Returns
*(ConnectableObservable)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.doAction(function (x) {
console.log('Side effect');
});
var published = source.publishLast();
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
var connection = published.connect();
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Side effect
// => Next: SourceA1
// => Completed
// => Next: SourceB1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/publishlast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/publishlast.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/publishlast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/publishlast.js)
================================================
FILE: doc/api/core/operators/publishvalue.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.publishValue([selector], initialValue)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/publishvalue.js "View in source")
Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence and starts with initialValue.
This operator is a specialization of `multicast` using a `Rx.BehaviorSubject`.
#### Arguments
1. `[selector]`: `Function` - Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will immediately receive the initial value, followed by all notifications of the source from the time of the subscription on.
2. `initialValue`: `Any` - Initial value received by observers upon subscription.
#### Returns
`ConnectableObservable` - An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function and initial value.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.tap(function (x) {
console.log('Side effect');
});
var published = source.publishValue(42);
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
var connection = published.connect();
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Next: SourceA42
// => Next: SourceB42
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/publishvalue.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/publishvalue.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/publishvalue.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/publishvalue.js)
================================================
FILE: doc/api/core/operators/range.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.range(start, count, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/range.js "View in source")
Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
### Arguments
1. `start` *(`Number`)*: The value of the first integer in the sequence.
2. `count` *(`Number`)*: The number of sequential integers to generate.
3. `[scheduler=Rx.Scheduler.currentThread]` *(`Scheduler`)*: Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
#### Returns
*(`Observable`)*: An observable sequence that contains a range of sequential integral numbers.
#### Example
```js
var source = Rx.Observable.range(0, 3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
```
### Location
File:
- [/src/core/perf/operators/range.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/range.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/range.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/range.js)
================================================
FILE: doc/api/core/operators/reduce.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.reduce(accumulator, [seed])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/reduce.js "View in source")
Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
For aggregation behavior with incremental intermediate results, see the [`scan`](scan.md) method.
#### Arguments
1. `accumulator` *(`Function`)*: An accumulator function to be invoked on each element with the following arguments:
1. `acc`: `Any` - the accumulated value.
2. `currentValue`: `Any` - the current value
3. `index`: `Number` - the current index
4. `source`: `Observable` - the current observable instance
2. `[seed]` *(`Any`)*: The initial accumulator value.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with the final accumulator value.
#### Example
```js
/* With a seed */
var source = Rx.Observable.range(1, 3)
.reduce(function (acc, x, idx, source) {
return acc * x;
}, 1)
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 6
// => Completed
/* Without a seed */
var source = Rx.Observable.range(1, 3)
.reduce(function (acc, x, idx, source) {
return acc * x;
})
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 6
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/reduce.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/reduce.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/reduce.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/reduce.js)
================================================
FILE: doc/api/core/operators/refcount.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `ConnectableObservable.prototype.refCount()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/connectableobservable.js "View in source")
Returns an observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence.
#### Returns
*(`Observable`)*: An observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.doAction(function (x) {
console.log('Side effect');
});
var published = source.publish().refCount();
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/connectableobservable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/connectableobservable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
Unit Tests:
- [`/tests/observable/connectableobservable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/connectableobservable.js)
================================================
FILE: doc/api/core/operators/repeat.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.repeat(value, [repeatCount], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/repeat.js "View in source")
Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
### Arguments
1. `value` *(`Any`)*: Element to repeat.
2. `[repeatCount=-1]` *(`Number`)*:Number of times to repeat the element. If not specified, repeats indefinitely.
3. `[scheduler=Rx.Scheduler.immediate]` *(`Scheduler`)*: Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
#### Returns
*(`Observable`)*: An observable sequence that repeats the given element the specified number of times.
#### Example
```js
var source = Rx.Observable.repeat(42, 3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
//=> Next: 42
// => Next: 42
// => Next: 42
// => Completed
```
### Location
File:
- [/src/core/perf/operators/repeat.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/repeat.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/repeat.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/repeat.js)
================================================
FILE: doc/api/core/operators/repeatproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.repeat(repeatCount)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/repeatproto.js "View in source")
Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
#### Arguments
1. `repeatCount` *(`Number`)*: Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
#### Returns
*(`Observable`)*: The observable sequence producing the elements of the given sequence repeatedly.
#### Example
```js
var source = Rx.Observable.range(1, 3)
.repeat(2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 1
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/repeatproto.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/repeatproto.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/repeat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/repeat.js)
================================================
FILE: doc/api/core/operators/repeatwhen.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.repeatWhen(notificationHandler)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/repeatwhen.js "View in source")
Returns an Observable that emits the same values as the source Observable with the exception of an onCompleted. An onCompleted notification from the source will result in the emission of a void item to the Observable provided as an argument to the notificationHandler function. If that Observable calls onComplete or onError then repeatWhen will call onCompleted or onError on the child subscription. Otherwise, this Observable will resubscribe to the source observable.
#### Arguments
1. `notificationHandler`: `Function` - receives an Observable of notifications with which a user can complete or error, aborting the repeat.
#### Returns
`Observable`: Observable modified with repeat logic
#### Example: Delayed repeat
```js
var source = Rx.Observable.just(42)
.repeatWhen(function(notifications) {
return notifications.scan(
function (acc, x, i) { return acc + i; }, 0)
.delay(200)
.takeWhile(function (count) {
return count < 1;
});
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// 200 ms pass
// => Next: 42
// 200 ms pass
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/repeatwhen.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/repeatwhen.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/repeatwhen.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/repeatwhen.js)
================================================
FILE: doc/api/core/operators/replay.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.replay([selector], [bufferSize], [window], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/replay.js "View in source")
Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
This operator is a specialization of `multicast` using a `Rx.ReplaySubject`.
#### Arguments
1. `[selector]` *(`Function`)*: Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.
2. `[bufferSize]` *(`Number`)*: Maximum element count of the replay buffer.
3. `[window]` *(`Number`)*: Maximum time length of the replay buffer in milliseconds.
4. `[scheduler]` *(`Scheduler`)*: Scheduler where connected observers within the selector function will be invoked on.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.do(function (x) {
console.log('Side effect');
});
var published = source
.replay(function (x) {
return x.take(2).repeat(2);
}, 3);
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Side effect
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceA0
// => Next: SourceA1
// => Completed
// => Side effect
// => Next: SourceB1
// => Next: SourceB0
// => Next: SourceB1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/replay.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/replay.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/replay.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/replay.js)
================================================
FILE: doc/api/core/operators/retry.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.retry([retryCount])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/retry.js "View in source")
Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
Note if you encounter an error and want it to retry once, then you must use .retry(2).
#### Arguments
1. `[retryCount]` *(`Number`)*: Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
#### Returns
*(`Observable`)*: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
#### Example
```js
var count = 0;
var source = Rx.Observable.interval(1000)
.selectMany(function () {
if (++count < 2) {
return Rx.Observable.throw(new Error());
}
return Rx.Observable.return(42);
})
.retry(3)
.take(1);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/retry.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/retry.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/retry.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/retry.js)
================================================
FILE: doc/api/core/operators/retrywhen.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.retryWhen(notifier)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/retrywhen.js "View in source")
Repeats the source observable sequence on error when the notifier emits a next value. If the source observable errors and the notifier completes, it will complete the source sequence.
#### Arguments
1. `notificationHandler` *(`Function`)*: A handler that is passed an observable sequence of errors raised by the source observable and returns
an observable that either continues, completes or errors. This behavior is then applied to the source observable.
#### Returns
*(`Observable`)*: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete.
#### Example: Delayed retry
```js
var source = Rx.Observable.interval(1000)
.map(function(n) {
if(n === 2) {
throw 'ex';
}
return n;
})
.retryWhen(function(errors) {
return errors.delay(200);
})
.take(6);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// 200 ms pass
// => Next: 0
// => Next: 1
// 200 ms pass
// => Next: 0
// => Next: 1
// => Completed
```
#### Example: Erroring an observable after 2 failures
```js
var source = Rx.Observable.interval(1000)
.map(function(n) {
if(n === 2) {
throw 'ex';
}
return n;
})
.retryWhen(function(errors) {
return errors.scan(function(errorCount, err) {
if(errorCount >= 2) {
throw err;
}
return errorCount + 1;
}, 0);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 0
// => Next: 1
// => Next: 0
// => Next: 1
// => Error: 'ex'
```
#### Example: Completing an observable after 2 failures
```js
var source = Rx.Observable.interval(1000)
.map(function(n) {
if(n === 2) {
throw 'ex';
}
return n;
})
.retryWhen(function(errors) {
return errors.scan(function(errorCount, err) {
return errorCount + 1;
}, 0).takeWhile(function(errorCount) {
return errorCount < 2;
});
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 0
// => Next: 1
// => Completed
```
#### Example: An incremental back-off strategy for handling errors
```js
Rx.Observable.create(function (o) {
console.log("subscribing");
o.onError(new Error("always fails"));
}).retryWhen(function (attempts) {
return Rx.Observable.range(1, 3).zip(attempts, function (i) { return i; }).flatMap(function (i) {
console.log("delay retry by " + i + " second(s)");
return Rx.Observable.timer(i * 1000);
});
}).subscribe();
/*
subscribing
delay retry by 1 second(s)
subscribing
delay retry by 2 second(s)
subscribing
delay retry by 3 second(s)
subscribing
*/
```
### Location
File:
- [`/src/core/linq/observable/retrywhen.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/retrywhen.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/retrywhen.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/retrywhen.js)
================================================
FILE: doc/api/core/operators/return.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.return(value, [scheduler])` ###
### `Rx.Observable.just(value, [scheduler])` ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/just.js "View in source")
Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
There is an alias called `returnValue` for browsers Next: 42
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/just.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/just.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/return.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/return.js)
================================================
FILE: doc/api/core/operators/sample.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.sample(interval | sampleObservable)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sample.js "View in source")
Samples the observable sequence at each interval.
#### Arguments
1. `[interval]` *(`Number`)*: Interval at which to sample (specified as an integer denoting milliseconds)
2. `[sampleObservable]` *(`Observable`)*: Sampler Observable.
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: Sampled observable sequence.
#### Example
```js
/* With an interval time */
var source = Rx.Observable.interval(1000)
.sample(5000)
.take(2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 4
// => Next: 9
// => Completed
/* With a sampler */
var source = Rx.Observable.interval(1000)
.sample(Rx.Observable.interval(5000))
.take(2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 4
// => Next: 9
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/sample.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sample.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/sample.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/sample.js)
================================================
FILE: doc/api/core/operators/scan.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.scan(accumulator, [seed])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/scan.js "View in source")
Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
For aggregation behavior with no intermediate results, see `Rx.Observable#reduce`.
Note the `Rx.Observable.prototype.scan([seed], accumulator)` has been removed as per v3.0 and replaced with `Rx.Observable.prototype.scan(accumulator, [seed])`.
#### Arguments
1. `accumulator` *(`Function`)*: An accumulator function to be invoked on each element with the following arguments:
1. `acc`: `Any` - the accumulated value.
2. `currentValue`: `Any` - the current value
3. `index`: `Number` - the current index
4. `source`: `Observable` - the current observable instance
2. `[seed]` *(`Any`)*: The initial accumulator value.
#### Returns
*(`Observable`)*: An observable sequence which results from the comonadic bind operation.
#### Example
```js
/* Without a seed */
var source = Rx.Observable.range(1, 3)
.scan(function (acc, x, i, source) { return acc + x; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 3
// => Next: 6
// => Completed
/* With a seed */
var source = Rx.Observable.range(1, 3)
.scan(function (acc, x, i, source) { return acc * x; }, 1);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 6
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/scan.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/scan.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/scan.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/scan.js)
================================================
FILE: doc/api/core/operators/select.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.select(selector, [thisArg])`
### `Rx.Observable.prototype.map(selector, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/map.js "View in source")
Projects each element of an observable sequence into a new form by incorporating the element's index. There is an alias for this method called `map`.
#### Arguments
1. `selector` *(`Function` | `Object`)*: Transform function to apply to each source element or an element to yield. If selector is a function, it is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Observable`)*: An observable sequence which results from the comonadic bind operation.
#### Example
```js
// Using a value
var md = Rx.Observable.fromEvent(document, 'mousedown').map(true);
var mu = Rx.Observable.fromEvent(document, 'mouseup').map(false);
// Using a function
var source = Rx.Observable.range(1, 3)
.select(function (x, idx, obs) {
return x * x;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 4
// => Next: 9
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/map.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/map.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/select.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/select.js)
================================================
FILE: doc/api/core/operators/selectmany.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.flatMap(selector, [resultSelector])`
### `Rx.Observable.prototype.selectMany(selector, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmap.js "View in source")
Aliases:
`Rx.Observable.prototype.flatMap`
and
`Rx.Observable.prototype.selectMany`
are equivalent.
One of the following:
Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences or Promises or array/iterable into one observable sequence.
```js
source.selectMany(function (x, i) { return Rx.Observable.range(0, x); });
source.selectMany(function (x, i) { return Promise.resolve(x + 1); });
source.selectMany(function (x, i) { return [x, i]; });
```
Projects each element of an observable sequence or Promise to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
```js
source.selectMany(function (x, i) { return Rx.Observable.range(0, x); }, function (x, y, ix, iy) { return x + y + ix + iy; });
source.selectMany(function (x, i) { return Promise.resolve(x + i); }, function (x, y, ix, iy) { return x + y + ix + iy; });
source.selectMany(function (x, i) { return [x, i]; }, function (x, y, ix, iy) { return x + y + ix + iy; });
```
Projects each element of the source observable sequence to the other observable sequence or Promise, or array/iterable and merges the resulting observable sequences into one observable sequence.
```js
source.selectMany(Rx.Observable.of(1,2,3));
source.selectMany(Promise.resolve(42));
source.selectMany([1,2,3]);
```
#### Arguments
1. `selector` *(`Function` | `Iterable` | `Promise`)*: An Object to project to the sequence or a transform function to apply to each element or an observable sequence to project each element from the source sequence onto. The selector is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[resultSelector]` *(`Function`)*: A transform function to apply to each element of the intermediate sequence. The resultSelector is called with the following information:
1. the value of the outer element
2. the value of the inner element
3. the index of the outer element
4. the index of the inner element
#### Returns
*(`Observable`)*: An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
#### Example
```js
var source = Rx.Observable
.range(1, 2)
.selectMany(function (x) {
return Rx.Observable.range(x, 2);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 2
// => Next: 3
// => Completed
/* Using a promise */
var source = Rx.Observable.of(1,2,3,4)
.selectMany(function (x, i) {
return Promise.resolve(x + i);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 3
// => Next: 5
// => Next: 7
// => Completed
/* Using an array */
Rx.Observable.of(2, 3, 5).selectMany(
function(x) {
// Return x^2, x^3 and x^4
return [
x * x,
x * x * x,
x * x * x * x
];
},
function(outer, inner, outerIndex, innerIndex) {
return { outer : outer, inner : inner, outerIdx : outerIndex, innerIdx : innerIndex };
}
).subscribe(
function(next) {
console.log(
'Outer: ' + next.outer + ', Inner: ' + next.inner +
', InnerIndex: ' + next.innerIdx + ', OuterIndex: ' + next.outerIdx
);
},
function() {
console.log('Completed');
}
);
//=> Outer: 2, Inner: 4, InnerIndex : 0, OuterIndex : 0
//=> Outer: 2, Inner: 8, InnerIndex : 1, OuterIndex : 0
//=> Outer: 2, Inner: 16, InnerIndex : 2, OuterIndex : 0
//=> Outer: 3, Inner: 9, InnerIndex : 0, OuterIndex : 1
//=> Outer: 3, Inner: 27, InnerIndex : 1, OuterIndex : 1
//=> Outer: 3, Inner: 81, InnerIndex : 2, OuterIndex : 1
//...etc
//=> Completed
```
### Location
File:
- [`/src/core/perf/operators/flatmap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/flatmap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/selectmany.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/selectmany.js)
* * *
================================================
FILE: doc/api/core/operators/sequenceequal.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.sequenceEqual(second, [comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sequenceequal.js "View in source")
Determins whether two sequences are equal by comparing the elements pairwise using a specified equality comparer.
#### Arguments
1. `second` *(`Observable` | `Promise` | `Array`)*: Second observable sequence, Promise or array to compare.
2. `[comparer]` *(`Function`)*: Comparer used to compare elements of both sequences.
#### Returns
*(`Observable`)*: An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.
#### Example
```js
var source1 = Rx.Observable.return(42);
var source2 = Rx.Observable.return(42);
var source = source1.sequenceEqual(source2);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/sequenceequal.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sequenceequal.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/sequenceequal.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/sequenceequal.js)
================================================
FILE: doc/api/core/operators/share.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.share()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/share.js "View in source")
Returns an observable sequence that shares a single subscription to the underlying sequence.
This operator is a specialization of `publish` which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
#### Example
```js
/* Without share */
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.doAction(function (x) {
console.log('Side effect');
});
source.subscribe(createObserver('SourceA'));
source.subscribe(createObserver('SourceB'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Side effect
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Completed
// => Side effect
// => Next: SourceB1
// => Completed
/* With share */
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.do(
function (x) {
console.log('Side effect');
});
var published = source.share();
// When the number of observers subscribed to published observable goes from
// 0 to 1, we connect to the underlying observable sequence.
published.subscribe(createObserver('SourceA'));
// When the second subscriber is added, no additional subscriptions are added to the
// underlying observable sequence. As a result the operations that result in side
// effects are not repeated per subscriber.
published.subscribe(createObserver('SourceB'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/share.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/share.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/publish.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/publish.js)
================================================
FILE: doc/api/core/operators/sharereplay.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.shareReplay([bufferSize], [window], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sharereplay.js "View in source")
Returns an observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
This operator is a specialization of `replay` that connects to the connectable observable sequence when the number of observers goes from zero to one, and disconnects when there are no more observers.
#### Arguments
1. `[bufferSize]` *(`Number`)*: Maximum element count of the replay buffer.
2. `[window]` *(`Number`)*: Maximum time length of the replay buffer in milliseconds.
3. `[scheduler]` *(`Scheduler`)*: Scheduler where connected observers within the selector function will be invoked on.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(4)
.doAction(function (x) {
console.log('Side effect');
});
var published = source
.shareReplay(3);
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
// Creating a third subscription after the previous two subscriptions have
// completed. Notice that no side effects result from this subscription,
// because the notifications are cached and replayed.
Rx.Observable
.return(true)
.delay(6000)
.flatMap(published)
.subscribe(createObserver('SourceC'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Side effect
// => Next: SourceA2
// => Next: SourceB2
// => Side effect
// => Next: SourceA3
// => Next: SourceB3
// => Completed
// => Completed
// => Next: SourceC1
// => Next: SourceC2
// => Next: SourceC3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/sharereplay.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sharereplay.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/replay.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/replay.js)
================================================
FILE: doc/api/core/operators/sharevalue.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.shareValue(value)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sharevalue.js "View in source")
Returns an observable sequence that shares a single subscription to the underlying sequence and starts with initialValue.
This operator is a specialization of `publishValue` which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.doAction(function (x) {
console.log('Side effect');
});
var published = source.shareValue(42);
published.subscribe(createObserver('SourceA'));
published.subscribe(createObserver('SourceB'));
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
}
// => Next: SourceA42
// => Next: SourceB42
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/sharevalue.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sharevalue.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/publishvalue.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/publishvalue.js)
================================================
FILE: doc/api/core/operators/single.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.single([predicate], [thisArg], [defaultValue])`
### `Rx.Observable.prototype.single([settings])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/first.js "View in source")
Returns a single element of an observable sequence that satisfies the condition in the predicate, or a default value if no such element exists. If no default value is given, then `onError` will be called. If there are more than one element that matches, then `onError` will be called.
#### Arguments
`Rx.Observable.prototype.single([predicate], [thisArg], [defaultValue])`
1. `[predicate]` *(`Function`)*: A predicate function to evaluate for elements in the source sequence. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
3. `[defaultValue]` *(`Any`)*: Default value if no such element exists.
`Rx.Observable.prototype.single([settings])`
1. `[settings]` *(`Object`)*: An object with the following fields
- `[predicate]` *(`Function`)*: A predicate function to evaluate for elements in the source sequence. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
- `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
- `[defaultValue]` *(`Any`)*: Default value if no such element exists.
#### Returns
*(`Observable`)*: An observable sequence that contains elements from the input sequence that satisfy the condition.
#### Example
```js
/* with a default value */
var source = Rx.Observable.empty().single({defaultValue: 42});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
/* With a predicate */
var source = Rx.Observable.range(0, 10)
.single(function (x, idx, obs) { return x === 1; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/single.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/single.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/single.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/single.js)
================================================
FILE: doc/api/core/operators/singleinstance.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Observable.prototype.singleInstance()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/singleinstance.js "View in source")
Returns a "cold" observable that becomes "hot" upon first subscription, and goes "cold" again when all subscriptions to it are disposed.
At first subscription to the returned observable, the source observable is subscribed to. That source subscription is then shared amongst each subsequent simultaneous subscription to the returned observable.
When all subscriptions to the returned observable have completed, the source observable subscription is disposed of.
The first subscription after disposal starts again, subscribing one time to the source observable, then sharing that subscription with each subsequent simultaneous subscription.
#### Returns
*(`Observable`)*: An observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence.
#### Example
```js
var interval = Rx.Observable.interval(1000);
var source = interval
.take(2)
.doAction(function (x) {
console.log('Side effect');
});
var single = source.singleInstance();
// two simultaneous subscriptions, lasting 2 seconds
single.subscribe(createObserver('SourceA'));
single.subscribe(createObserver('SourceB'));
setTimeout(function(){
// resubscribe two times again, more than 5 seconds later,
// long after the original two subscriptions have ended
single.subscribe(createObserver('SourceC'));
single.subscribe(createObserver('SourceD'));
}, 5000);
function createObserver(tag) {
return Rx.Observer.create(
function (x) {
console.log('Next: ' + tag + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed: ' + tag);
});
}
// => Side effect
// => Next: SourceA0
// => Next: SourceB0
// => Side effect
// => Next: SourceA1
// => Next: SourceB1
// => Completed: SourceA
// => Completed: SourceB
// => Side effect
// => Next: SourceC0
// => Next: SourceD0
// => Side effect
// => Next: SourceC1
// => Next: SourceD1
// => Completed: SourceC
// => Completed: SourceD
```
### Location
File:
- [`/src/core/linq/observable/singleinstance.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/singleinstance.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.binding.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
Unit Tests:
- [`/tests/observable/singleinstance.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/singleinstance.js)
================================================
FILE: doc/api/core/operators/skip.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.skip(count)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/skip.js "View in source")
Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
#### Arguments
1. `count` *(`Number`)*: The number of elements to skip before returning the remaining elements.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements that occur after the specified index in the input sequence.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.skip(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/skip.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/skip.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/skip.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/skip.js)
================================================
FILE: doc/api/core/operators/skiplast.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.skipLast(count)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skiplast.js "View in source")
Bypasses a specified number of elements at the end of an observable sequence.
This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
#### Arguments
1. `count` *(`Number`)*: Number of elements to bypass at the end of the source sequence.
#### Returns
*(`Observable`)*: An observable sequence containing the source sequence elements except for the bypassed ones at the end.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.skipLast(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/skiplast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skiplast.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/skiplast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/skiplast.js)
================================================
FILE: doc/api/core/operators/skiplastwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.skipLastWithTime(duration, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skiplastwithtime.js "View in source")
Bypasses a specified number of elements at the end of an observable sequence.
This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
#### Arguments
1. `duration` *(`Number`)*: Duration for skipping elements from the end of the sequence.
1. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the timer on. If not specified, defaults to timeout scheduler.
#### Returns
*(`Observable`)*: An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.take(10)
.skipLastWithTime(5000);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/skiplastwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skiplastwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/skiplastwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/skiplastwithtime.js)
================================================
FILE: doc/api/core/operators/skipuntil.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.skipUntil(other)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/skipuntil.js "View in source")
Returns the values from the source observable sequence only after the other observable sequence produces a value.
#### Arguments
1. `other` *(`Observable` | `Promise`)*: The observable sequence or Promise that triggers propagation of elements of the source sequence.
#### Returns
*(`Observable`)*: An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.skipUntil(Rx.Observable.timer(5000));
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 6
// => Next: 7
// => Next: 8
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/skipuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/skipuntil.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/skipuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/skipuntil.js)
================================================
FILE: doc/api/core/operators/skipuntilwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.skipUntilWithTime(startTime, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skipuntilwithtime.js "View in source")
Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
#### Arguments
1. `startTime` *(`Date` | `Number`)*: Time to start taking elements from the source sequence. If this value is less than or equal to current time, no elements will be skipped.
2. [`scheduler = Rx.Scheduler.timeout`] *(`Scheduler`)*: Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
#### Returns
*(`Observable`)*: An observable sequence with the elements skipped until the specified start time.
#### Example
```js
// Using relative time
var source = Rx.Observable.timer(0, 1000)
.skipUntilWithTime(5000);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 6
// => Next: 7
// => Next: 8
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/skipuntilwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skipuntilwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/skipuntilwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/skipuntilwithtime.js)
================================================
FILE: doc/api/core/operators/skipwhile.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.skipWhile(predicate, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skipwhile.js "View in source")
Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each source element for a condition. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
#### Example
```js
// With a predicate
var source = Rx.Observable.range(1, 5)
.skipWhile(function (x) { return x < 3; });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 3
// => Next: 4
// => Next: 5
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/skipwhile.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/skipwhile.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/skipwhile.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/skipwhile.js)
================================================
FILE: doc/api/core/operators/slice.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.slice([begin], [end])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/slice.js "View in source")
The `slice` method returns a shallow copy of a portion of an Observable into a new Observable object. Unlike the `Array` version, this does not support negative numbers for begin or end.
#### Arguments
1. `[begin]`: `Any`: Zero-based index at which to begin extraction. If omitted, this will default to zero.
2. `[end]` `Number`: Zero-based index at which to end extraction. slice extracts up to but not including end.
#### Returns
`Observable`: A shallow copy of a portion of an Observable into a new Observable object.
#### Example
```js
/* Without an end */
var source = Rx.Observable.of(1,2,3,1,2,3)
.slice(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 3
// => Completed
/* With an end */
var source = Rx.Observable.of(1,2,3,1,2,3)
.slice(2, 1);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/slice.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/slice.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/slice.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/slice.js)
================================================
FILE: doc/api/core/operators/some.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.some([predicate], [thisArg])` ###
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/some.js "View in source")
Determines whether any element of an observable sequence satisfies a condition if present, else if any items are in the sequence.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each element for a condition.
2. `[thisArg]` *(`Any`)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: An observable sequence containing a single element determining whether one of the elements in the source sequence pass the test in the specified predicate.
#### Example
```js
var source = Rx.Observable.of(1,2,3,4,5)
.some(function (x) { return x % 2 === 0; });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: true
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/some.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/some.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/some.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/some.js)
================================================
FILE: doc/api/core/operators/spawn.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.spawn(fn)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/spawn.js "View in source")
Spawns a generator function which allows for Promises, Observable sequences, Arrays, Objects, Generators and functions.
#### Arguments
1. `fn` *(`Function`)*: The spawning function.
#### Returns
*(`Observable`)*: An Observable with the final result
#### Example
```js
var Rx = require('rx');
var spawned = Rx.Observable.spawn(function* () {
var a = yield cb => cb(null, 'a');
var b = yield ['b'];
var c = yield Rx.Observable.just('c');
var d = yield Rx.Observable.just('d');
var e = yield Promise.resolve('e');
return a + b + c + d + e;
});
spawned.subscribe(
function (x) { console.log('next %s', x); },
function (e) { console.log('error %s', e); },
function () { console.log('completed'); }
);
// => next 'abcde'
// => completed
```
### Location
File:
- [/src/core/linq/observable/spawn.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/spawn.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
Unit Tests:
- [``/tests/observable/spawn.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/spawn.js)
================================================
FILE: doc/api/core/operators/start.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.start(func, [context], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/start.js "View in source")
Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence.
### Arguments
1. `func` *(`Function`)*: Function to run asynchronously.
2. `[context]` *(`Any`)*: The context for the func parameter to be executed. If not specified, defaults to undefined.
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
#### Returns
*(`Observable`)*: An observable sequence exposing the function's result value, or an exception.
#### Example
```js
var context = { value: 42 };
var source = Rx.Observable.start(
function () {
return this.value;
},
context,
Rx.Scheduler.timeout
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [/src/core/linq/observable/start.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/start.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using rx.async.js | rx.async.compat.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/start.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/start.js)
================================================
FILE: doc/api/core/operators/startasync.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.startAsync(functionAsync)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/startasync.js "View in source")
Invokes the asynchronous function, surfacing the result through an observable sequence.
### Arguments
1. `functionAsync` *(`Function`)*: Asynchronous function which returns a Promise to run.
#### Returns
*(`Observable`)*: An observable sequence exposing the function's Promises's value or error.
#### Example
```js
var source = Rx.Observable.startAsync(function () {
return RSVP.Promise.resolve(42);
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [/src/core/linq/observable/startasync.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/startasync.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/startasync.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/start.js)
================================================
FILE: doc/api/core/operators/startwith.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.startWith([scheduler] ...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/startwith.js "View in source")
Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
#### Arguments
1. `[scheduler]` *(`Scheduler`)*: Scheduler to execute the function.
2. `args` *(arguments)*: Values to prepend to the observable sequence.
#### Returns
*(`Observable`)*: The source sequence prepended with the specified values.
#### Example
```js
var source = Rx.Observable.return(4)
.startWith(1, 2, 3)
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/startwith.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/startwith.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/startwith.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/startwith.js)
================================================
FILE: doc/api/core/operators/subscribe.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.subscribe([observer] | [onNext], [onError], [onCompleted])`
### `Rx.Observable.prototype.forEach([observer] | [onNext], [onError], [onCompleted])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js "View in source")
Subscribes an observer to the observable sequence.
#### Arguments
1. `[observer]` *(Observer)*: The object that is to receive notifications.
1. `[onNext]` *(`Function`)*: Function to invoke for each element in the observable sequence.
2. `[onError]` *(`Function`)*: Function to invoke upon exceptional termination of the observable sequence.
3. `[onCompleted]` *(`Function`)*: Function to invoke upon graceful termination of the observable sequence.
#### Returns
*(Disposable)*: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
#### Example
```js
/* With no arguments */
var source = Rx.Observable.range(0, 3)
.do(function (x) { console.log('Do Next: ' + x); });
var subscription = source.subscribe();
// => Do Next: 0
// => Do Next: 1
// => Do Next: 2
/* With an observer */
var observer = Rx.Observer.create(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
var source = Rx.Observable.range(0, 3)
var subscription = source.subscribe(observer);
// => Next: 0
// => Next: 1
// => Next: 2
/* Using functions */
var source = Rx.Observable.range(0, 3)
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
```
### Location
File:
- [`/src/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/core/observable.js)
================================================
FILE: doc/api/core/operators/subscribeon.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.subscribeOn(scheduler)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/subscribeon.js "View in source")
Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler.
This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer callbacks on a scheduler, use `observeOn`.
#### Arguments
1. `scheduler` *(`Scheduler`)*: Scheduler to notify observers on.
#### Returns
*(`Observable`)*: The source sequence whose observations happen on the specified scheduler.
#### Example
```js
var observable = Rx.Observable.create(function (observer) {
function handler () {
observer.onNext(42);
observer.onCompleted();
}
// Change scheduler for here
var id = setTimeout(handler, 1000);
return function () {
// And change scheduler for here
if (id) clearTimeout(id);
};
});
// Change the scheduler to timeout for subscribe/unsubscribe
var source = observable.subscribeOn(Rx.Scheduler.timeout);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/subscribeon.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/subscribeon.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [`/tests/observable/subscribeon.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/subscribeon.js)
================================================
FILE: doc/api/core/operators/subscribeoncompleted.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.subscribeOnCompleted(onCompleted, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js "View in source")
Subscribes a function to invoke upon graceful termination of the observable sequence.
#### Arguments
1. `onCompleted` *(`Function`)*: Function to invoke upon graceful termination of the observable sequence.
2. `[thisArg]` *(`Any`)*: Object to use as this when executing callback.
#### Returns
*(Disposable)*: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
#### Example
```js
/* Using functions */
var source = Rx.Observable.range(0, 3);
var subscription = source.subscribeOnCompleted(
function () {
console.log('Completed');
});
// => Completed
/* With a thisArg */
var source = Rx.Observable.range(0, 3);
var subscription = source.subscribeOnCompleted(
function (err) {
this.log('Completed');
}, console);
// => Completed
```
### Location
File:
- [`/src/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/core/observable.js)
================================================
FILE: doc/api/core/operators/subscribeonerror.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.subscribeOnError(onError, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js "View in source")
Subscribes a function to invoke upon exceptional termination of the observable sequence.
#### Arguments
1. `onError` *(`Function`)*: Function to invoke upon exceptional termination of the observable sequence.
2. `[thisArg]` *(`Any`)*: Object to use as this when executing callback.
#### Returns
*(Disposable)*: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
#### Example
```js
/* Using functions */
var source = Rx.Observable.throw(new Error());
var subscription = source.subscribeOnError(
function (err) {
console.log('Error: %s', err);
});
// => Error: Error
/* With a thisArg */
var source = Rx.Observable.throw(new Error());
var subscription = source.subscribeOnError(
function (err) {
this.log('Error: %s', err);
}, console);
// => Error: Error
```
### Location
File:
- [`/src/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/core/observable.js)
================================================
FILE: doc/api/core/operators/subscribeonnext.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.subscribeOnNext(onNext, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js "View in source")
Subscribes a function to invoke for each element in the observable sequence.
#### Arguments
1. `onNext` *(`Function`)*: Function to invoke for each element in the observable sequence.
2. `[thisArg]` *(`Any`)*: Object to use as this when executing callback.
#### Returns
*(Disposable)*: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
#### Example
```js
/* Using functions */
var source = Rx.Observable.range(0, 3)
var subscription = source.subscribeOnNext(
function (x) {
console.log('Next: %s', x);
});
// => Next: 0
// => Next: 1
// => Next: 2
/* With a thisArg */
var source = Rx.Observable.range(0, 3)
var subscription = source.subscribeOnNext(
function (x) {
this.log('Next: %s', x);
}, console);
// => Next: 0
// => Next: 1
// => Next: 2
```
### Location
File:
- [`/src/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/observable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/core/observable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/core/observable.js)
================================================
FILE: doc/api/core/operators/sum.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.sum([keySelector], [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sum.js "View in source")
Computes the sum of a sequence of values that are obtained by invoking an optional transform function on each element of the input sequence, else if not specified computes the sum on each item in the sequence.
#### Arguments
1. `[keySelector]` *(`Scheduler`)*: A transform function to apply to each element. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
#### Returns
*(`Observable`)*: An observable sequence containing a single element with the sum of the values in the source sequence.
#### Example
```js
/* Without a selector */
var source = Rx.Observable.range(1, 10)
.sum();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 55
// => Completed
/* With a selector */
var array = [
{ value: 1 },
{ value: 2 },
{ value: 3 }
];
var source = Rx.Observable
.from(array)
.sum(function (x, idx, obs) {
return x.value;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 6
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/sum.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/sum.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
Prerequisites:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/sum.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/sum.js)
================================================
FILE: doc/api/core/operators/switch.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.switch()`
### `Rx.Observable.prototype.switchLatest()` *DEPRECATED*
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/switch.js "View in source")
Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. There is an alias for this method called `switchLatest` for browsers Next: 0
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/switch.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/switch.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/switch.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/switch.js)
* * *
================================================
FILE: doc/api/core/operators/switchfirst.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.switchFirst()` ##
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/switchfirst.js "View in source")
Receives an `Observable` of `Observables` and propagates the first `Observable` exclusively until it completes before it begins subscribes to the next `Observable`. Observables that come before the current Observable completes will be dropped and will not propagate.
This operator is similar to `concatAll()` except that it will not hold onto Observables that come in before the current one is finished completed.
#### Returns
*(`Observable`)*: An Observable sequence that is the result of concatenating non-overlapping items emitted by an Observable of Observables.
#### Example
```javascript
//Generate an event every 100 milliseconds
var source = Rx.Observable.generateWithRelativeTime(
0,
function(x) {return x < 5; },
function(x) {return x + 1; },
function(x) {return x; },
function(x) {return 100; })
.map(function(value) {
//Observable takes 150 milliseconds to complete
return Rx.Observable.timer(150).map(value);
});
source.exclusive().subscribe(
function (x) {
console.log("Next %d", x);
}, function(e) {
console.log("Error %s", e);
}, function() {
console.log("Completed");
});
// Next 0
// Next 2
// Next 4
// Completed
```
#### Location
File:
- [`/src/core/linq/observable/switchfirst.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/switchfirst.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
- [`rx.experimental-lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental-lite.js)
- [`rx.experimental-lite-compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental-lite-compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental/)
Unit Tests:
- None
================================================
FILE: doc/api/core/operators/take.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.take(count, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/take.js "View in source")
Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of `take(0)`.
#### Arguments
1. `count` *(`Number`)*: The number of elements to return.
2. `[scheduler]` *(`Scheduler`)*: Scheduler used to produce an onCompleted message in case `count` is set to 0.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements before and including the specified index in the input sequence.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/take.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/take.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/take.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/take.js)
================================================
FILE: doc/api/core/operators/takelast.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeLast(count)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelast.js "View in source")
Returns a specified number of contiguous elements from the end of an observable sequence, using an optional scheduler to drain the queue.
This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
#### Arguments
1. `count` *(`Number`)*: Number of elements to bypass at the end of the source sequence.
#### Returns
*(`Observable`)*: An observable sequence containing the source sequence elements except for the bypassed ones at the end.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.takeLast(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/takelast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelast.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/takelast.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takelast.js)
================================================
FILE: doc/api/core/operators/takelastbuffer.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeLastBuffer(count)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelastbuffer.js "View in source")
Returns an array with the specified number of contiguous elements from the end of an observable sequence.
#### Arguments
1. `count` *(`Number`)*: Number of elements to bypass at the end of the source sequence.
#### Returns
*(`Observable`)*: An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.takeLastBuffer(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 2,3,4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/takelastbuffer.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelastbuffer.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/takelastbuffer.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takelastbuffer.js)
================================================
FILE: doc/api/core/operators/takelastbufferwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeLastBufferWithTime(duration, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelastbufferwithtime.js "View in source")
Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
This operator accumulates a queue with a length enough to store elements received during the initial duration window. As more elements are received, elements older than the specified duration are taken from the queue and produced on the result sequence. This causes elements to be delayed with duration.
#### Arguments
1. `duration` *(`Number`)*: Duration for taking elements from the end of the sequence.
2. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the timer on. If not specified, defaults to timeout scheduler.
#### Returns
*(`Observable`)*: An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
#### Example
```js
var source = Rx.Observable
.timer(0, 1000)
.take(10)
.takeLastBufferWithTime(5000);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 5,6,7,8,9
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/takelastbufferwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelastbufferwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/takelastbufferwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takelastbufferwithtime.js)
* * *
================================================
FILE: doc/api/core/operators/takelastwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeLastWithTime(duration, [timeScheduler], [loopScheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelastwithtime.js "View in source")
Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
#### Arguments
1. `duration` *(`Number`)*: Duration for taking elements from the end of the sequence.
2. `[timeScheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the timer on. If not specified, defaults to timeout scheduler.
2. `[loopScheduler=Rx.Scheduler.currentThread]` *(`Scheduler`)*: Scheduler to drain the collected elements. If not specified, defaults to current thread scheduler.
#### Returns
*(`Observable`)*: An observable sequence with the elements taken during the specified duration from the end of the source sequence.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.take(10)
.takeLastWithTime(5000);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 5
// => Next: 6
// => Next: 7
// => Next: 8
// => Next: 9
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/takelastwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takelastwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/skipuntilwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takelastwithtime.js)
================================================
FILE: doc/api/core/operators/takeuntil.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeUntil(other)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/takeuntil.js "View in source")
Returns the values from the source observable sequence until the other observable sequence or Promise produces a value.
#### Arguments
1. `other` *(`Observable` | `Promise`)*: Observable sequence or Promise that terminates propagation of elements of the source sequence.
#### Returns
*(`Observable`)*: An observable sequence containing the elements of the source sequence up to the point the other sequence or Promise interrupted further propagation.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.takeUntil(Rx.Observable.timer(5000));
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/takeuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/takeuntil.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/takeuntil.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takeuntil.js)
================================================
FILE: doc/api/core/operators/takeuntilwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeUntilWithTime(endTime, [scheduler])`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takeuntil.js "View in source")
Returns the values from the source observable sequence until the end time.
#### Arguments
1. `endTime` *(`Date` | `Number`)*: Time to stop taking elements from the source sequence. If this value is less than or equal to the current time, the result stream will complete immediately.
2. [`scheduler`] *(`Scheduler`)*: Scheduler to run the timer on.
#### Returns
*(`Observable`)*: An observable sequence with the elements taken until the specified end time.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.takeUntilWithTime(5000);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Next: 3
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/takeuntilwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takeuntilwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/takeuntilwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takeuntilwithtime.js)
================================================
FILE: doc/api/core/operators/takewhile.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.takeWhile(predicate, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takewhile.js "View in source")
Returns elements from an observable sequence as long as a specified condition is true.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each source element for a condition. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as this when executing callback.
#### Returns
*(`Observable`)*: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.
#### Example
```js
// With a predicate
var source = Rx.Observable.range(1, 5)
.takeWhile(function (x) { return x < 3; });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/takewhile.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/takewhile.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/takewhile.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/takewhile.js)
================================================
FILE: doc/api/core/operators/thendo.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.thenDo(selector)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/thendo.js "View in source")
Matches when the observable sequence has an available value and projects the value.
#### Arguments
1. `selector` *(`Function`)*: Selector that will be invoked for values in the source sequence.
#### Returns
*(`Plan`)*: Plan that produces the projected values, to be fed (with other plans) to the when operator.
#### Example
```js
var selector = function (x, y) { return x + ", " + y; };
var source = Rx.Observable.when(
Rx.Observable.interval(250).and(Rx.Observable.of("A", "B", "C")).thenDo(selector),
Rx.Observable.interval(300).and(Rx.Observable.of("a", "b")).thenDo(selector)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0, A
// => Next: 0, a
// => Next: 1, B
// => Next: 1, b
// => Next: 2, C
// => Completed
```
### Location
File:
- [/src/core/linq/observable/thendo.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/thendo.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.joinpatterns.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.joinpatterns.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-JoinPatterns`](http://www.nuget.org/packages/RxJS-JoinPatterns)
Unit Tests:
- [/tests/observable/when.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/when.js)
================================================
FILE: doc/api/core/operators/throttle.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.throttle(windowDuration, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/throttle.js "View in source")
Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
#### Arguments
1. `windowDuration` *(`Number`)*: Time to wait before emitting another item after emitting the last item (specified as an integer denoting milliseconds).
2. `[scheduler]` *(`Scheduler`)*: The Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to the default scheduler.
#### Returns
*(`Observable`)*: An Observable that performs the throttle operation.
#### Example
```js
var times = [
{ value: 0, time: 100 },
{ value: 1, time: 600 },
{ value: 2, time: 400 },
{ value: 3, time: 900 },
{ value: 4, time: 200 }
];
// Delay each item by time and project value;
var source = Rx.Observable.from(times)
.flatMap(function (item) {
return Rx.Observable
.of(item.value)
.delay(item.time);
})
.throttle(300 /* ms */);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 2
// => Next: 3
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/throttle.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/throttle.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/throttle.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/throttle.js)
================================================
FILE: doc/api/core/operators/throw.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.throw(exception, [scheduler])`
### `Rx.Observable.throwError(exception, [scheduler])`
### `Rx.Observable.throwException(exception, [scheduler])` ** DEPRECATED **
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/throw.js "View in source")
Returns an observable sequence that terminates with an exception, using the specified scheduler to send out the single onError message.
### Arguments
1. `exception` *(Error)*: Error the observable sequence terminates with.
2. `[scheduler=Rx.Scheduler.immediate]` *(`Scheduler`)*: Scheduler to send the exceptional termination call on. If not specified, defaults to the immediate scheduler.
#### Returns
*(`Observable`)*: The observable sequence that terminates exceptionally with the specified exception object.
#### Example
```js
var source = Rx.Observable.return(42)
.selectMany(Rx.Observable.throw(new Error('error!')));
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Error: Error: error!
```
### Location
File:
- [/src/core/perf/operators/throw.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/throw.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/throw.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/throw.js)
================================================
FILE: doc/api/core/operators/timeinterval.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.timeInterval([scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timeinterval.js "View in source")
Records the time interval between consecutive values in an observable sequence.
#### Arguments
1. `[scheduler=Rx.Observable.timeout]` *(`Scheduler`)*: Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence with time interval information on values.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.timeInterval()
.map(function (x) { return x.value + ':' + x.interval; })
.take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0:0
// => Next: 1:1000
// => Next: 2:1000
// => Next: 3:1000
// => Next: 4:1000
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/timeinterval.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timeinterval.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- If using `rx.time.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/timeinterval.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/timeinterval.js)
================================================
FILE: doc/api/core/operators/timeout.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.timeout(dueTime, [other], [scheduler])`
### `Rx.Observable.prototype.timeout([firstTimeout], timeoutDurationSelector, [other])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timeout.js "View in source")
Returns the source observable sequence or the other observable sequence if dueTime elapses.
--OR--
Returns the source observable sequence, switching to the other observable sequence if a timeout is signaled.
#### Arguments
If using a relative or absolute time:
1. `dueTime` *(Date | Number)*: Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) when a timeout occurs.
2. `[other]` *(`Observable` | `Promise` | `Error`)*: Observable sequence or Promise to return in case of a timeout. If a string is specified, then an error will be thrown with the given error message. If not specified, a timeout error throwing sequence will be used.
3. `[scheduler]` *(`Scheduler`)*: Scheduler to run the timeout timers on. If not specified, the default scheduler is used.
If using a timeout duration selector:
1. `[firstTimeout]` *(`Observable`)*: Observable sequence that represents the timeout for the first element. If not provided, this defaults to `Rx.Observable.never()`.
2. `timeoutDurationSelector` *(`Function`)*: Selector to retrieve an observable sequence that represents the timeout between the current element and the next element.
3. `[other]` *(`Scheduler`)*:Sequence to return in case of a timeout. If not provided, this is set to `Observable.throw`
#### Returns
*(`Observable`)*: An observable sequence with time interval information on values.
#### Example
```js
/* With no other */
var source = Rx.Observable
.just(42)
.delay(5000)
.timeout(200);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Error: Error: Timeout
/* With message */
var source = Rx.Observable
.just(42)
.delay(5000)
.timeout(200, new Error('Timeout has occurred.'));
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Error: Error: Timeout has occurred.
/* With an observable */
var source = Rx.Observable
.just(42)
.delay(5000)
.timeout(200, Rx.Observable.empty());
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Completed
/* With a Promise */
var source = Rx.Observable
.just(42)
.delay(5000)
.timeout(200, Promise.resolve(42));
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
/* without a first timeout */
var array = [
200,
300,
350,
400
];
var source = Rx.Observable
.for(array, function (x) { return Rx.Observable.timer(x); })
.map(function (x, i) { return i; })
.timeout(function (x) { return Rx.Observable.timer(400); });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Error: Error: Timeout
/* With no other */
var array = [
200,
300,
350,
400
];
var source = Rx.Observable
.for(array, function (x) { return Rx.Observable.timer(x); })
.map(function (x, i) { return i; })
.timeout(
Rx.Observable.timer(250),
function (x) { return Rx.Observable.timer(400); }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Error: Error: Timeout
/* With other */
var array = [
200,
300,
350,
400
];
var source = Rx.Observable
.for(array, function (x) { return Rx.Observable.timer(x); })
.map(function (x, i) { return i; })
.timeout(
Rx.Observable.timer(250),
function (x) { return Rx.Observable.timer(400); },
Rx.Observable.just(42)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 1
// => Next: 2
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/timeout.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timeout.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/timeout.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/timeout.js)
================================================
FILE: doc/api/core/operators/timer.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.timer(dueTime, [period], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timer.js "View in source")
Returns an observable sequence that produces a value after dueTime has elapsed and then after each period. Note for `rx.lite.js`, only
relative time is supported.
### Arguments
1. `dueTime` *(Date|Number)*: Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
2. `[period|scheduler=Rx.Scheduler.timeout]` *(Number|Scheduler)*: Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the timer on. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence that produces a value after due time has elapsed and then each period.
#### Example
```js
var source = Rx.Observable.timer(200, 100)
.timeInterval()
.pluck('interval')
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 200
// => Next: 100
// => Next: 100
// => Completed
```
### Location
File:
- [/src/core/linq/observable/timer.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timer.js)
- [/src/core/linq/observable/timer-lite.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timer-lite.js)
Dist:
- [rx.all.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [rx.all.compat.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [rx.time.js](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).time.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | rx.lite.compat.js
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/timer.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/timer.js)
================================================
FILE: doc/api/core/operators/timestamp.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.timestamp([scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timestamp.js "View in source")
Records the timestamp for each value in an observable sequence.
#### Arguments
1. `[scheduler=Rx.Observable.timeout]` *(`Scheduler`)*: Scheduler used to compute timestamps. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence with timestamp information on values.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.timestamp()
.map(function (x) { return x.value + ':' + x.timestamp; })
.take(5);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0:1378690776351
// => Next: 1:1378690777313
// => Next: 2:1378690778316
// => Next: 3:1378690779317
// => Next: 4:1378690780319
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/timestamp.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/timestamp.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/timestamp.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/timestamp.js)
================================================
FILE: doc/api/core/operators/toarray.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.toArray()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/toarray.js "View in source")
Creates a list from an observable sequence.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with a list containing all the elements of the source sequence.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.take(5)
.toArray();
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: [0,1,2,3,4]
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/toarray.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/toarray.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/toarray.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/toarray.js)
================================================
FILE: doc/api/core/operators/toasync.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.toAsync(func, [context], [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/toasync.js "View in source")
Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
### Arguments
1. `func` *(`Function`)*: Function to convert to an asynchronous function.
2. `[context]` *(`Any`)*: The context for the func parameter to be executed. If not specified, defaults to undefined.
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
#### Returns
*(`Function`)*: Asynchronous function.
#### Example
```js
var func = Rx.Observable.toAsync(function (x, y) {
return x + y;
});
// Execute function with 3 and 4
var source = func(3, 4);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 7
// => Completed
```
### Location
File:
- [/src/core/linq/observable/toasync.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/toasync.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).async.js | rx.async.compat.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`rx`](https://www.npmjs.org/package/rx)JS-Binding
Unit Tests:
- [/tests/observable/toasync.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/toasync.js)
================================================
FILE: doc/api/core/operators/tomap.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.toMap(keySelector, [elementSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/tomap.js "View in source")
Converts the observable sequence to a Map if it exists. Note that this only works in an ES6 environment or polyfilled.
#### Arguments
1. `keySelector` *(`Function`)*: A function which produces the key for the Map.
2. `[elementSelector]` *(`Function`)*: An optional function which produces the element for the Map. If not present, defaults to the value from the observable sequence.
#### Returns
*(`Observable`)*: An observable sequence with a single value of a Map containing the values from the observable sequence.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.take(5)
.toMap(function (x) { return x * 2; }, function (x) { return x * 4; });
var subscription = source.subscribe(
function (x) {
var arr = [];
x.forEach(function (value, key) { arr.push(value, key); })
console.log('Next: ' + arr);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: [0,0,2,4,4,8,6,12,8,16]
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/tomap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/tomap.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/tomap.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/tomap.js)
================================================
FILE: doc/api/core/operators/topromise.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.toPromise([promiseCtor])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/topromise.js "View in source")
Converts an Observable sequence to a ES2015 compliant promise.
#### Arguments
1. `[promiseCtor]` *(Promise)*: An ES2015 compliant Promise that can be created. This is optional. If your runtime already supports ES2015 promises, you do not need to fill in this parameter. Alternatively you can specify an ES2015 complaint promise via `Rx.config.Promise`
#### Returns
*(`Promise`)*: An ES2015 compliant promise which contains the last value from the Observable sequence. If the Observable sequence is in error, then the Promise will be in the rejected stage. If the sequence is empty, the Promise will not resolve.
#### Example
```es6
/* Using normal ES2015 */
let source = Rx.Observable
.just(42)
.toPromise();
source.then((value) => console.log('Value: %s', value));
// => Value: 42
/* Rejected Promise */
/* Using normal ES2015 */
let source = Rx.Observable
.throw(new Error('woops'))
.toPromise();
source
.then((value) => console.log('Value: %s', value))
.catch((err) => console.log('Error: %s', err));
// => Error: Error: woops
/* Setting via the config */
Rx.config.Promise = RSVP.Promise;
let source = Rx.Observable
.just(42)
.toPromise();
source.then((value) => console.log('Value: %s', value));
// => Value: 42
/* Setting via the method */
let source = Rx.Observable
.just(42)
.toPromise(RSVP.Promise);
source.then((value) => console.log('Value: %s', value));
// => Value: 42
```
### Location
File:
- [`/src/core/linq/observable/topromise.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/topromise.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/fromnodecallback.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/topromise.js)
================================================
FILE: doc/api/core/operators/toset.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.toSet()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/toset.js "View in source")
Creates an observable sequence with a single item of a Set created from the observable sequence. Note that this only works in an ES6 environment or polyfilled.
#### Returns
*(`Observable`)*: An observable sequence containing a single element with a Set containing all the elements of the source sequence.
#### Example
```js
var source = Rx.Observable.timer(0, 1000)
.take(5)
.toSet();
var subscription = source.subscribe(
function (x) {
var arr = [];
x.forEach(function (i) { arr.push(i); })
console.log('Next: ' + arr);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: [0,1,2,3,4]
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/toset.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/toset.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
Unit Tests:
- [`/tests/observable/toset.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/toset.js)
================================================
FILE: doc/api/core/operators/transduce.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.transduce(transducer)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/transduce.js "View in source")
Executes a transducer to transform the observable sequence.
Transducers are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes such as Observable sequences. Transducers compose directly, without awareness of input or creation of intermediate aggregates.
Such examples of transducers libraries are [transducers-js](https://github.com/cognitect-labs/transducers-js) from Cognitect and [transducers.js](https://github.com/jlongster/transducers.js) from James Long.
In order for this operator to work, the transducers library must follow the following contract:
```js
return {
'@@transducer/init': function() {
// Return the item
return observer;
},
'@@transducer/step': function(obs, input) {
// Process next item
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
// Mark completion
return obs.onCompleted();
}
};
```
### Arguments
1. `transducer` *(`Transducer`)*: A transducer to execute.
#### Returns
*(`Observable`)*: An observable sequence that results from the transducer execution.
#### Example
Below is an example using [transducers-js](https://github.com/cognitect-labs/transducers-js).
```js
function even (x) { return x % 2 === 0; }
function mul10(x) { return x * 10; }
var t = transducers
var source = Rx.Observable.range(1, 5)
.transduce(t.comp(t.filter(even), t.map(mul10)));
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 20
// => Next: 40
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/transduce.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/transduce.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/transduce.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/transduce.js)
================================================
FILE: doc/api/core/operators/using.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.using(resourceFactory, observableFactory)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/using.js "View in source")
Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
### Arguments
1. `resourceFactory` *(`Function`)*: Factory function to obtain a resource object.
2. `observableFactory` *(`Function`)*: Factory function to obtain an observable sequence that depends on the obtained resource.
#### Returns
*(`Function`)*: An observable sequence whose lifetime controls the lifetime of the dependent resource object.
#### Example
```js
/* Using an AsyncSubject as a resource which supports the .dispose method */
function DisposableResource(value) {
this.value = value;
this.disposed = false;
}
DisposableResource.prototype.getValue = function () {
if (this.disposed) {
throw new Error('Object is disposed');
}
return this.value;
};
DisposableResource.prototype.dispose = function () {
if (!this.disposed) {
this.disposed = true;
this.value = null;
}
console.log('Disposed');
};
var source = Rx.Observable.using(
function () { return new DisposableResource(42); },
function (resource) {
var subject = new Rx.AsyncSubject();
subject.onNext(resource.getValue());
subject.onCompleted();
return subject;
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
subscription.dispose();
// => Disposed
```
### Location
File:
- [`/src/core/linq/observable/using.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/using.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
Unit Tests:
- [`/tests/observable/using.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/using.js)
================================================
FILE: doc/api/core/operators/when.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.when(...args)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/when.js "View in source")
A series of plans (specified as an Array or as a series of arguments) created by use of the Then operator on patterns.
### Arguments
1. `args` *(arguments|Array)*: A series of plans (specified as an Array of as a series of arguments) created by use of the then operator on patterns.
#### Returns
*(`Observable`)*: Observable sequence with the results form matching several patterns.
#### Example
```js
// Fire each plan when both are ready
var source = Rx.Observable.when(
Rx.Observable.timer(100).and(Rx.Observable.timer(500)).thenDo(function (x, y) { return 'first'; }),
Rx.Observable.timer(400).and(Rx.Observable.timer(300)).thenDo(function (x, y) { return 'second'; })
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: second
// => Next: first
// => Completed
```
#### Example
```js
var chopsticks = [new Rx.Subject(), new Rx.Subject(), new Rx.Subject()];
var hungry = [new Rx.Subject(), new Rx.Subject(), new Rx.Subject()];
var eat = i => {
return () => {
setTimeout(() => {
console.log('Done');
chopsticks[i].onNext({});
chopsticks[(i+1) % 3].onNext({});
}, 1000);
return 'philosopher ' + i + ' eating';
};
};
var dining = Rx.Observable.when(
hungry[0].and(chopsticks[0]).and(chopsticks[1]).thenDo(eat(0)),
hungry[1].and(chopsticks[1]).and(chopsticks[2]).thenDo(eat(1)),
hungry[2].and(chopsticks[2]).and(chopsticks[0]).thenDo(eat(2))
);
dining.subscribe(console.log.bind(console));
chopsticks[0].onNext({}); chopsticks[1].onNext({}); chopsticks[2].onNext({});
for (var i = 0; i < 3; i++) {
hungry[0].onNext({}); hungry[1].onNext({}); hungry[2].onNext({});
}
```
### Location
File:
- [`/src/core/linq/observable/when.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/when.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.joinpatterns.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.joinpatterns.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).joinpatterns.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All)
- [`RxJS-JoinPatterns`](http://www.nuget.org/packages/RxJS-JoinPatterns)
Unit Tests:
- [`/tests/observable/when.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/when.js)
================================================
FILE: doc/api/core/operators/where.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.filter(predicate, [thisArg])`
### `Rx.Observable.prototype.where(predicate, [thisArg])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/filter.js "View in source")
Filters the elements of an observable sequence based on a predicate.
#### Arguments
1. `predicate` *(`Function`)*: A function to test each source element for a condition. The callback is called with the following information:
1. the value of the element
2. the index of the element
3. the Observable object being subscribed
2. `[thisArg]` *(`Any`)*: Object to use as `this` when executing the predicate.
#### Returns
*(`Observable`)*: An observable sequence that contains elements from the input sequence that satisfy the condition.
#### Example
```js
var source = Rx.Observable.range(0, 5)
.filter(function (x, idx, obs) {
return x % 2 === 0;
});
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0
// => Next: 2
// => Next: 4
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/filter.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/filter.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/where.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/where.js)
================================================
FILE: doc/api/core/operators/while.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.while(condition, source)`
### `Rx.Observable.whileDo(condition, source)` *DEPRECATED*
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/while.js "View in source")
Repeats source as long as condition holds emulating a while loop. There is an alias for this method called 'whileDo' for browsers Next: 42
// => Next: 42
// => Next: 42
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/while.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/while.js)
Dist:
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental)
Unit Tests:
- [`/tests/observable/while.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/while.js)
================================================
FILE: doc/api/core/operators/window.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.window()`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/window.js "View in source")
The `window` method periodically subdivide items from an Observable into Observable windows and emit these windows rather than emitting the items one at a time.
Window is similar to `buffer`, but rather than emitting packets of items from the original `Observable`, it emits Observables, each one of which emits a subset of items from the original `Observable` and then terminates with an `onCompleted` call.
Like `buffer`, `window` has many varieties, each with its own way of subdividing the original `Observable` into the resulting `Observable` emissions, each one of which contains a "window" onto the original emitted items. In the terminology of the `window` method, when a window "opens," this means that a new `Observable` is emitted and that `Observable` will begin emitting items emitted by the source `Observable`. When a window "closes," this means that the emitted Observable stops emitting items from the source Observable and calls its Subscribers' `onCompleted` method and terminates.
#### With window closing selector
```js
Rx.Observable.prototype.window(windowClosingSelector);
```
This version of `window` opens its first window immediately. It closes the currently open window and immediately opens a new one each time it observes an object emitted by the `Observable` that is returned from `windowClosingSelector`. In this way, this version of `window` emits a series of non-overlapping windows whose collective `onNext` emissions correspond one-to-one with those of the source Observable.
#### Arguments
1. `windowClosingSelector` *(`Function`)*: A function invoked to define the closing of each produced window.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
// With closings
var source = Rx.Observable.timer(0, 50)
.window(function () { return Rx.Observable.timer(125); })
.take(3)
.flatMap(function (x) { return x.toArray(); });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2
// => Next: 3,4,5
// => Next: 6,7
// => Completed
```
#### With window opening and window closing selector
```js
Rx.Observable.prototype.window(windowOpenings, windowClosingSelector);
```
This version of `window` opens a window whenever it observes the `windowOpenings` `Observable` emit an Opening object and at the same time calls `windowClosingSelector` to generate a closing `Observable` associated with that window. When that closing `Observable` emits an object, `window` closes that window. Since the closing of currently open windows and the opening of new windows are activities that are regulated by independent Observables, this version of `window` may create windows that overlap (duplicating items from the source `Observable`) or that leave gaps (discarding items from the source Observable).
#### Arguments
1. `windowOpenings` *(`Observable`)*: Observable sequence whose elements denote the creation of new windows
2. `windowClosingSelector` *(`Function`)*: A function invoked to define the closing of each produced window.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
/* Using Openings and Closing Selector */
var openings = Rx.Observable.interval(200);
var source = Rx.Observable.interval(50)
.window(openings, function (x) { return Rx.Observable.timer(x + 100); })
.take(3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 3,4
// => Next: 7,8
// => Next: 11,12
// => Completed
```
#### With boundaries
```js
Rx.Observable.prototype.window(windowBoundaries);
```
This version of `window` returns an `Observable` that emits non-overlapping buffered items from the source `Observable` each time the specified boundary Observable emits an item.
#### Arguments
1. `windowBoundaries` *(`Observable`)*: Sequence of window boundary markers. The current window is closed and a new window is opened upon receiving a boundary marker.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
/* With window boundaries */
var openings = Rx.Observable.interval(500);
// Convert the window to an array
var source = Rx.Observable.timer(0, 100)
.window(openings)
.take(3)
.flatMap(function (x) { return x.toArray(); });
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2,3,4
// => Next: 5,6,7,8,9,10
// => Next: 11,12,13,14,15
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/window.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/window.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
Unit Tests:
- [`/tests/observable/window.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/window.js)
================================================
FILE: doc/api/core/operators/windowwithcount.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.windowWithCount(count, [skip])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/windowwithcount.js "View in source")
Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
#### Arguments
1. `count` *(`Number`)*: Length of each buffer.
2. `[skip]` *(`Number`)*: Number of elements to skip between creation of consecutive windows. If not provided, defaults to the count.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
/* Without a skip */
var source = Rx.Observable.range(1, 6)
.windowWithCount(2)
.selectMany(function (x) { return x.toArray(); });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1,2
// => Next: 3,4
// => Next: 5,6
// => Next:
// => Completed
/* Using a skip */
var source = Rx.Observable.range(1, 6)
.windowWithCount(2, 1)
.selectMany(function (x) { return x.toArray(); });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 1,2
// => Next: 2,3
// => Next: 3,4
// => Next: 4,5
// => Next: 5,6
// => Next: 6
// => Next:
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/windowwithcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/windowwithcount.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/windowwithcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/windowwithcount.js)
================================================
FILE: doc/api/core/operators/windowwithtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.windowWithTime(timeSpan, [timeShift | scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/windowwithtime.js "View in source")
Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
#### Arguments
1. `timeSpan` *(`Number`)*: Length of each buffer (specified as an integer denoting milliseconds).
2. `[timeShift]` *(`Number`)*: Interval between creation of consecutive buffers (specified as an integer denoting milliseconds).
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence of buffers.
#### Example
```js
/* Without a skip */
var source = Rx.Observable.interval(100)
.windowWithTime(500)
.take(3);
var subscription = source.subscribe(
function (child) {
child.toArray().subscribe(
function (x) {
console.log('Child Next: ' + x.toString());
},
function (err) {
console.log('Child Error: ' + err);
},
function () {
console.log('Child Completed');
}
);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Child Next: 0,1,2,3
// => Child Completed
// => Completed
// => Child Next: 4,5,6,7,8
// => Child Completed
// => Child Next: 9,10,11,12,13
// => Child Completed
/* Using a skip */
var source = Rx.Observable.interval(100)
.windowWithTime(500, 100)
.take(3);
var subscription = source.subscribe(
function (child) {
child.toArray().subscribe(
function (x) {
console.log('Child Next: ' + x.toString());
},
function (err) {
console.log('Child Error: ' + err);
},
function () {
console.log('Child Completed');
}
);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Completed
// => Child Next: 0,1,2,3,4
// => Child Completed
// => Child Next: 0,1,2,3,4,5
// => Child Completed
// => Child Next: 1,2,3,4,5,6
// => Child Completed
```
### Location
File:
- [`/src/core/linq/observable/windowwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/windowwithtime.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/windowwithtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/windowwithtime.js)
================================================
FILE: doc/api/core/operators/windowwithtimeorcount.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.windowWithTimeOrCount(timeSpan, count, [scheduler])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/windowwithtimeorcount.js "View in source")
Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
#### Arguments
1. `timeSpan` *(`Number`)*: Maximum time length of a window.
2. `count` *(`Number`)*: Maximum element count of a window.
3. `[scheduler=Rx.Scheduler.timeout]` *(`Scheduler`)*: Scheduler to run windows timers on. If not specified, the timeout scheduler is used.
#### Returns
*(`Observable`)*: An observable sequence of windows.
#### Example
```js
/* Hitting the count buffer first */
var source = Rx.Observable.interval(100)
.windowWithTimeOrCount(500, 3)
.take(3)
.selectMany(function (x) { return x.toArray(); });
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2
// => Next: 3,4,5
// => Next: 6,7,8
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/windowwithtimeorcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/windowwithtimeorcount.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
Unit Tests:
- [`/tests/observable/windowwithtimeorcount.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/windowwithtimeorcount.js)
================================================
FILE: doc/api/core/operators/withlatestfrom.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.withLatestFrom(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/withlatestfrom.js "View in source")
Merges the specified observable sequences into one observable sequence by using the selector function only when the source observable sequence (the instance) produces an element. The other observables can be in the form of an argument list of observables or an array. If the result selector is omitted, a list with the elements will be yielded.
#### Arguments
1. `args` *(arguments | Array)*: An array or arguments of Observable sequences.
1. `[resultSelector]` *(`Function`)*: Function to invoke when the instance source observable produces an element. If omitted, a list with the elements will be yielded.
#### Returns
*(`Observable`)*: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
#### Example
```js
/* Have staggering intervals */
var source1 = Rx.Observable.interval(140)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(50)
.map(function (i) { return 'Second: ' + i; });
// When source1 emits a value, combine it with the latest emission from source2.
var source = source1.withLatestFrom(
source2,
function (s1, s2) { return s1 + ', ' + s2; }
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: First: 0, Second: 1
// => Next: First: 1, Second: 4
// => Next: First: 2, Second: 7
// => Next: First: 3, Second: 10
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/withlatestfrom.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/withlatestfrom.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/withlatestfrom.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/withlatestfrom.js)
================================================
FILE: doc/api/core/operators/wrap.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.wrap(fn)`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/spawn.js "View in source")
Wrap the given generator `fn` into a function that returns an Observable.
#### Arguments
1. `fn` *(`Function`)*: A generator function to wrap.
#### Returns
*(`Function`)*: A function once executed, returns an Observable.
#### Example
```js
var Rx = require('rx');
var fn = Rx.Observable.wrap(function* (val) {
return yield Rx.Observable.just(val);
});
fn(42).subscribe(
function (x) { console.log('next %s', x); },
function (e) { console.log('error %s', e); },
function () { console.log('completed'); }
);
// => next 42
// => completed
```
### Location
File:
- [/src/core/linq/observable/spawn.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/spawn.js)
Dist:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js)
- [`rx.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
Prerequisites:
- If using `rx.async.js` | `rx.async.compat.js`
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async)
Unit Tests:
- [`/tests/observable/spawn.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/spawn.js)
================================================
FILE: doc/api/core/operators/zip.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.zip(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/zip.js "View in source")
Merges the specified observable sequences or Promises into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. If the result selector function is omitted, a list with the elements of the observable sequences at corresponding indexes will be yielded.
#### Arguments
1. `args` *(Array|arguments)*: Observable sources.
2. `[resultSelector]` *(Function)*: A function which takes the inputs at the specified index and combines them together. If omitted, a list with the elements of the observable sequences at corresponding indexes will be yielded.
#### Returns
*(`Observable`)*: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
#### Example
```js
/* Without a result selector */
var range = Rx.Observable.range(0, 5);
var source = Rx.Observable.zip(
range,
range.skip(1),
range.skip(2)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2
// => Next: 1,2,3
// => Next: 2,3,4
// => Completed
/* With a result selector */
var range = Rx.Observable.range(0, 5);
var source = Rx.Observable.zip(
range,
range.skip(1),
range.skip(2),
function (s1, s2, s3) {
return s1 + ':' + s2 + ':' + s3;
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0:1:2
// => Next: 1:2:3
// => Next: 2:3:4
// => Completed
/* Using promises and Observables */
var range = Rx.Observable.range(0, 5);
var source = Rx.Observable.zip(
Promise.resolve(0),
Promise.resolve(1),
Rx.Observable.return(2),
function (s1, s2, s3) {
return s1 + ':' + s2 + ':' + s3;
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0:1:2
// => Completed
```
### Location
File:
- [/src/core/linq/observable/zip.js](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/zip.js)
Dist:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- [`rx`](https://www.npmjs.org/package/rx).experimental.js
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [/tests/observable/zip.js](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/zip.js)
================================================
FILE: doc/api/core/operators/zipiterable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.zipIterable(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/zipiterable.js "View in source")
Merges the current observable sequence with iterables such as `Map`, `Array`, `Set` into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
#### Arguments
1. `args` *(`Arguments`)*: Arguments of Arrays, Maps, Sets or other iterables.
2. `[resultSelector]` *(Function)*: A function which takes the inputs at the specified index and combines them together. If omitted, a list with the elements of the observable sequences at corresponding indexes will be yielded.
#### Returns
*(`Observable`)*: An observable sequence containing the result of combining elements of the sources using the specified result selector function. If omitted, a list with the elements of the observable sequences at corresponding indexes will be yielded.
#### Example
```js
var array = [3, 4, 5];
var source = Rx.Observable.range(0, 3)
.zipIterable(
array,
function (s1, s2) { return s1 + ':' + s2; }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0:3
// => Next: 1:4
// => Next: 2:5
// => Completed
```
### Location
File:
- [`/src/core/linq/observable/zipiterable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/zipiterable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/zip.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/zip.js)
================================================
FILE: doc/api/core/operators/zipproto.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.Observable.prototype.zip(...args, [resultSelector])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/zip.js "View in source")
Merges the specified observable sequences or Promises into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
#### Arguments
1. `args` *(`Arguments` | `Array`)*: Arguments or an array of observable sequences.
2. `[resultSelector]` *(Function)*: A function which takes the inputs at the specified index and combines them together. If omitted, a list with the elements of the observable sequences at corresponding indexes will be yielded.
#### Returns
*(`Observable`)*: An observable sequence containing the result of combining elements of the sources using the specified result selector function.
#### Example
```js
/* Without a result selector */
var range = Rx.Observable.range(0, 5);
var source = range.zip(
range.skip(1),
range.skip(2)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0,1,2
// => Next: 1,2,3
// => Next: 2,3,4
// => Completed
/* Using arguments */
var range = Rx.Observable.range(0, 5);
var source = range.zip(
range.skip(1),
range.skip(2),
function (s1, s2, s3) {
return s1 + ':' + s2 + ':' + s3;
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 0:1:2
// => Next: 1:2:3
// => Next: 2:3:4
// => Completed
```
### Location
File:
- [`/src/core/perf/operators/zip.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/perf/operators/zip.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/observable/zip.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/zip.js)
================================================
FILE: doc/api/disposables/compositedisposable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.CompositeDisposable` class #
Represents a group of disposable resources that are disposed together.
## Usage ##
The follow example shows the basic usage of an Rx.CompositeDisposable.
```js
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
// Initialize with two disposables
var disposables = new Rx.CompositeDisposable(d1, d2);
disposables.dispose();
// => one
// => two
```
### Location
- rx.js
## `CompositeDisposable Constructor` ##
- [`constructor`](#rxcompositedisposablergs)
## `CompositeDisposable Instance Methods` ##
- [`add`](#rxcompositedisposableprototypeadditem)
- [`dispose`](#rxcompositedisposableprototypedispose)
- [`remove`](#rxcompositedisposableprototyperemoveitem)
- [`toArray`](#rxcompositedisposableprototypetoarray)
## `CompositeDisposable Instance Properties` ##
- [`isDisposed`](#isdisposed)
- [`length`](#length)
## _CompositeDisposable Constructor_ ##
### `Rx.CompositeDisposable(...args)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L5-L9 "View in source")
Initializes a new instance of the `Rx.CompositeDisposable` class from a group of disposables.
#### Arguments
1. `args` *(Array|arguments)*: Disposables that will be disposed together.
#### Example
```js
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
// Initialize with two disposables
var disposables = new Rx.CompositeDisposable(d1, d2);
disposables.dispose();
// => one
// => two
```
### Location
- rx.js
* * *
## _CompositeDisposable Instance Methods_ ##
### `Rx.CompositeDisposable.prototype.add(item)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L17-L24 "View in source")
Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
#### Arguments
1. `item` *(Disposable)*: Disposable to add.
#### Example
```js
var disposables = new Rx.CompositeDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
disposables.add(d1);
disposables.dispose();
// => one
```
### Location
- rx.js
* * *
### `Rx.CompositeDisposable.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L49-L60 "View in source")
Disposes all disposables in the group and removes them from the group.
#### Example
```js
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
var disposables = new Rx.CompositeDisposable(d1, d2);
disposables.dispose();
// => one
// => two
console.log(disposables.length);
// => 0
```
### Location
- rx.js
* * *
### `Rx.CompositeDisposable.prototype.remove(item)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L31-L44 "View in source")
Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
#### Arguments
1. `item` *(Disposable)*: Disposable to remove.
#### Returns
*(Boolean)*: `true` if the disposable was found and disposed; otherwise, `false`.
#### Example
```js
var disposables = new Rx.CompositeDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
disposables.add(d1);
console.log(disposables.remove(d1));
// => true
```
### Location
- rx.js
* * *
### `Rx.CompositeDisposable.prototype.toarray()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L87-L89 "View in source")
Converts the existing CompositeDisposable to an array of disposables. Does not dispose the objects.
#### Returns
*(Array)*: An array of disposable objects.
#### Example
```js
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
var disposables = new Rx.CompositeDisposable(d1, d2);
var array = disposables.toArray();
console.log(array.length);
// => 2
```
### Location
- rx.js
* * *
## _CompositeDisposable Instance Properties_ ##
### `isDisposed`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L7 "View in source")
Gets a value that indicates whether the object is disposed.
#### Example
```js
var disposables = new Rx.CompositeDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('disposed');
});
disposables.add(d1);
console.log(disposables.isDisposed);
// => false
disposables.dispose();
// => disposed
console.log(disposables.isDisposed);
// => true
```
### Location
- rx.js
* * *
### `length`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/compositedisposable.js#L8 "View in source")
Gets the number of disposables in the CompositeDisposable.
#### Example
```js
var disposables = new Rx.CompositeDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('disposed');
});
disposables.add(d1);
console.log(disposables.length);
// => 1
disposables.dispose();
// => disposed
console.log(disposables.length);
// => 0
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/disposables/disposable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.Disposable` class #
Provides a set of static methods for creating Disposables, which defines a method to release allocated resources.
## Usage ##
The follow example shows the basic usage of an `Rx.Disposable`.
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
disposable.dispose();
// => disposed
```
## `Disposable Class Methods` ##
- [`create`](#rxdisposablecreateaction)
- [`isDisposable`](#rxdisposableisdisposabled)
## `Disposable Class Properties` ##
- [`empty`](#rxdisposableempty)
## `Disposable Instance Methods` ##
- [`dispose`](#rxdisposableprototypedispose)
## _Class Methods_ ##
### `Rx.Disposable.create(action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js"View in source")
Creates a disposable object that invokes the specified action when disposed.
#### Arguments
1. `action` *(Function)*: Function to run during the first call to `dispose`. The action is guaranteed to be run at most once.
#### Returns
*(Disposable)*: The disposable object that runs the given action upon disposal.
#### Example
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
disposable.dispose();
// => disposed
```
### Location
File:
- [`/src/core/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/disposables/disposable.js)
* * *
### `Rx.Disposable.isDisposable(d)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js"View in source")
Creates a disposable object that invokes the specified action when disposed.
#### Arguments
1. `d` *(Object)*: Object to validate whether it has a dispose method.
#### Returns
*(Boolean)*: `true` if is a disposable object, else `false`.
#### Example
```js
var disposable = Rx.Disposable.empty;
console.log(disposable.isDisposable(disposable));
// => true
```
### Location
File:
- [`/src/core/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/disposables/disposable.js)
* * *
## _Disposable Class Properties_ ##
### `Rx.Disposable.empty`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js#L130 "View in source")
Gets the disposable that does nothing when disposed.
#### Returns
*(Disposable)*: The disposable that does nothing when disposed.
#### Example
```js
var disposable = Rx.Disposable.empty;
disposable.dispose(); // Does nothing
```
### Location
File:
- [`/src/core/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/disposables/disposable.js)
* * *
## _Disposable Instance Methods_ ##
### `Rx.Disposable.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js#L13-L18 "View in source")
Performs the task of cleaning up resources.
#### Example
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
disposable.dispose();
// => disposed
```
### Location
### Location
File:
- [`/src/core/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/disposable.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
Prerequisites:
- None
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Complete`](http://www.nuget.org/packages/RxJS-Complete)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
Unit Tests:
- [`/tests/disposables/disposable.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/disposables/disposable.js)
* * *
================================================
FILE: doc/api/disposables/refcountdisposable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.RefCountDisposable` class #
Represents a disposable resource that only disposes its underlying disposable resource when all `getDisposable` dependent disposable objects have been disposed.
## Usage ##
The follow example shows the basic usage of an `Rx.RefCountDisposable`.
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
var refCountDisposable = new Rx.RefCountDisposable(disposable);
var disposable1 = refCountDisposable.getDisposable();
var disposable2 = refCountDisposable.getDisposable();
disposable1.dispose();
console.log(disposable.isDisposed);
// => false
disposable2.dispose();
console.log(disposable.isDisposed);
// => false
refCountDisposable.dispose();
// => disposed
console.log(refCountDisposable.isDisposed);
// => true
```
### Location
- rx.js
## `RefCountDisposable Constructor` ##
- [`constructor`](#rxrefcountdisposabledisposable)
## `RefCountDisposable Instance Methods` ##
- [`dispose`](#rxrefcountdisposableprototypedispose)
- [`getDisposable`](#rxrefcountdisposableprototypegetdisposable)
## `RefCountDisposable Instance Properties` ##
- [`isDisposed`](#isdisposed)
## _RefCountDisposable Constructor_ ##
### `Rx.RefCountDisposable(disposable)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/rxrefcountdisposable.js#L7-L10 "View in source")
Initializes a new instance of the `Rx.RefCountDisposable` class with the specified disposable
#### Arguments
1. `disposable` *(Disposable)*: Underlying disposable.
#### Example
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
var refCountDisposable = new Rx.RefCountDisposable(disposable);
console.log(refCountDisposable.isDisposed);
// => false
```
### Location
- rx.js
* * *
## _RefCountDisposable Instance Methods_ ##
### `Rx.RefCountDisposable.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/rxrefcountdisposable.js#L30-L35 "View in source")
Disposes the underlying disposable only when all dependent disposables have been disposed.
#### Example
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
var refCountDisposable = new Rx.RefCountDisposable(disposable);
var disposable1 = refCountDisposable.getDisposable();
var disposable2 = refCountDisposable.getDisposable();
disposable1.dispose();
console.log(disposable.isDisposed);
// => false
disposable2.dispose();
console.log(disposable.isDisposed);
// => false
refCountDisposable.dispose();
// => disposed
console.log(refCountDisposable.isDisposed);
// => true
```
### Location
- rx.js
* * *
### `Rx.RefCountDisposable.prototype.getDisposable()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/rxrefcountdisposable.js#L18-L20 "View in source")
Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
#### Returns
*(Disposable)*: A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
#### Example
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
var refCountDisposable = new Rx.RefCountDisposable(disposable);
var d = refCountDisposable.getDisposable();
console.log(d === disposable);
// => false
// Clean up disposables
disposable.dispose();
d.dispose();
// Now try to dispose the main
refCountDisposable.dispose();
console.log(refCountDisposable.isDisposed);
// => true
```
### Location
- rx.js
* * *
## _RefCountDisposable Instance Properties_ ##
### `isDisposed`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/rxrefcountdisposable.js#L8 "View in source")
Gets a value that indicates whether the object is disposed.
#### Example
```js
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
var refCountDisposable = new Rx.RefCountDisposable(disposable);
disposable.dispose();
console.log(refCountDisposable.isDisposed);
// => false
refCountDisposable.dispose();
// => disposed
console.log(refCountDisposable.isDisposed);
// => true
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/disposables/serialdisposable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.SerialDisposable` class #
Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource.
## Usage ##
The follow example shows the basic usage of an Rx.SerialDisposable.
```js
var serialDisposable = new Rx.SerialDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
serialDisposable.setDisposable(d1);
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
serialDisposable.setDisposable(d2);
// => one
serialDisposable.dispose();
// = two
```
### Location
- rx.js
## `SerialDisposable Constructor` ##
- [`constructor`](#rxserialdisposable)
## `SerialDisposable Instance Methods` ##
- [`dispose`](#rxserialdisposableprototypedispose)
- [`getDisposable`](#rxserialdisposableprototypegetdisposable)
- [`setDisposable`](#rxserialdisposableprototypesetdisposable)
## `SerialDisposable Instance Properties` ##
- [`isDisposed`](#isdisposed)
## _SerialDisposable Constructor_ ##
### `Rx.SerialDisposable()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/serialdisposable.js#L5-L8 "View in source")
Initializes a new instance of the `Rx.SerialDisposable` class.
#### Example
```js
var serialDisposable = new Rx.SerialDisposable();
console.log(serialDisposable.isDisposed);
// => false
```
### Location
- rx.js
* * *
## _SerialDisposable Instance Methods_ ##
### `Rx.SerialDisposable.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/serialdisposable.js#L50-L60 "View in source")
Disposes the underlying disposable as well as all future replacements.
#### Example
```js
var serialDisposable = new Rx.SerialDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
serialDisposable.setDisposable(disposable);
serialDisposable.dispose();
// => one
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
// => two
```
### Location
- rx.js
* * *
### `Rx.SerialDisposable.prototype.getDisposable()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/serialdisposable.js#L16-L18 "View in source")
Gets the underlying disposable.
#### Returns
*(Disposable)*: The underlying disposable.
#### Example
```js
var serialDisposable = new Rx.SerialDisposable();
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
serialDisposable.setDisposable(disposable);
var d = serialDisposable.getDisposable();
console.log(d === disposable);
```
### Location
- rx.js
* * *
### `Rx.SerialDisposable.prototype.setDisposable(value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/serialdisposable.js#L24-L36 "View in source")
Sets the underlying disposable.
#### Arguments
1. `value` *(Disposable)*: The new underlying disposable.
#### Example
```js
var serialDisposable = new Rx.SerialDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
serialDisposable.setDisposable(d1);
serialDisposable.dispose();
// => one
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
serialDisposable.setDisposable(d2);
// => two
```
### Location
- rx.js
* * *
## _SerialDisposable Instance Properties_ ##
### `isDisposed`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/serialdisposable.js#L6 "View in source")
Gets a value that indicates whether the object is disposed.
#### Example
```js
var serialDisposable = new Rx.SerialDisposable();
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
serialDisposable.setDisposable(disposable);
console.log(serialDisposable.isDisposed);
// => false
serialDisposable.dispose();
// => disposed
console.log(serialDisposable.isDisposed);
// => true
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/disposables/singleassignmentdisposable.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.SingleAssignmentDisposable` class #
Represents a disposable resource which only allows a single assignment of its underlying disposable resource. If an underlying disposable resource has already been set, future attempts to set the underlying disposable resource will throw an Error.
## Usage ##
The follow example shows the basic usage of an Rx.SingleAssignmentDisposable.
```js
var singleDisposable = new Rx.SingleAssignmentDisposable();
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
singleDisposable.setDisposable(disposable);
singleDisposable.dispose();
// => disposed
```
### Location
- rx.js
## `SingleAssignmentDisposable Constructor` ##
- [`constructor`](#rxsingleassignmentdisposable)
## `SingleAssignmentDisposable Instance Methods` ##
- [`dispose`](#rxsingleassignmentdisposableprototypedispose)
- [`getDisposable`](#rxsingleassignmentdisposableprototypegetdisposable)
- [`setDisposable`](#rxsingleassignmentdisposableprototypesetdisposable)
## `SingleAssignmentDisposable Instance Properties` ##
- [`isDisposed`](#isdisposed)
## _SingleAssignmentDisposable Constructor_ ##
### `Rx.SingleAssignmentDisposable()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/singleassignmentdisposable.js#L7-L10 "View in source")
Initializes a new instance of the `Rx.SingleAssignmentDisposable` class.
#### Example
```js
var singleDisposable = new Rx.SingleAssignmentDisposable();
console.log(singleDisposable.isDisposed);
// => false
```
### Location
- rx.js
* * *
## _SingleAssignmentDisposable Instance Methods_ ##
### `Rx.SingleAssignmentDisposable.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/singleassignmentdisposable.js#L47-L57 "View in source")
Disposes the underlying disposable.
#### Example
```js
var singleDisposable = new Rx.SingleAssignmentDisposable();
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
singleDisposable.setDisposable(disposable);
console.log(singleDisposable.isDisposed);
// => false
singleDisposable.dispose();
// => disposed
console.log(singleDisposable.isDisposed);
// => true
```
### Location
- rx.js
* * *
### `Rx.SingleAssignmentDisposable.prototype.getDisposable()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/singleassignmentdisposable.js#L18-L20 "View in source")
Gets the underlying disposable. After disposal, the result of getting this method is undefined.
#### Returns
*(Disposable)*: The underlying disposable.
#### Example
```js
var singleDisposable = new Rx.SingleAssignmentDisposable();
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
singleDisposable.setDisposable(disposable);
var d = singleDisposable.getDisposable();
console.log(d === disposable);
```
### Location
- rx.js
* * *
### `Rx.SingleAssignmentDisposable.prototype.setDisposable(value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/singleassignmentdisposable.js#L31-L42 "View in source")
Sets the underlying disposable.
#### Arguments
1. `value` *(Disposable)*: The new underlying disposable.
#### Example
```js
var singleDisposable = new Rx.SingleAssignmentDisposable();
var d1 = Rx.Disposable.create(function () {
console.log('one');
});
singleDisposable.setDisposable(d1);
var d2 = Rx.Disposable.create(function () {
console.log('two');
});
try {
singleDisposable.setDisposable(d2);
} catch (e) {
console.log(e.message);
}
// => Disposable has already been assigned
```
### Location
- rx.js
* * *
## _SingleAssignmentDisposable Instance Properties_ ##
### `isDisposed`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/disposables/singleassignmentdisposable.js#L8 "View in source")
Gets a value that indicates whether the object is disposed.
#### Example
```js
var singleDisposable = new Rx.SingleAssignmentDisposable();
var disposable = Rx.Disposable.create(function () {
console.log('disposed');
});
singleDisposable.setDisposable(disposable);
console.log(singleDisposable.isDisposed);
// => false
singleDisposable.dispose();
// => disposed
console.log(singleDisposable.isDisposed);
// => true
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/helpers/readme.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Reactive Extensions Helpers #
Helper functions for the Reactive Extensions for JavaScript
## Documentation ##
- [`Rx.helpers.defaultComparer`](#rxhelpersdefaultcomparerx-y)
- [`Rx.helpers.defaultSubComparer`](#rxhelpersdefaultsubscomparerx-y)
- [`Rx.helpers.defaultError`](#rxhelpersdefaulterror)
- [`Rx.helpers.identity`](#rxhelpersidentityx)
- [`Rx.helpers.isPromise`](#rxhelpersispromisep)
- [`Rx.helpers.noop`](#rxhelpersnoop)
* * *
### `Rx.helpers.defaultComparer(x, y)`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
The default equality comparer, used when a comparer is not supplied to a function. Uses an internal deep equality check.
#### Arguments
1. `x` *(Any)*: The first value to compare
2. `y` *(Any)*: The second value to compare
#### Returns
*(Boolean)*: `true` if equal; else `false`.
#### Example
```js
var comparer = Rx.helpers.defaultComparer;
// Should return true
var x = 42, y = 42
console.log(comparer(x, y));
// => true
// Should return false
var x = new Date(0), y = new Date();
console.log(comparer(x, y));
// => false
```
* * *
### `Rx.helpers.defaultSubcomparer(x, y)`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
The default comparer to determine whether one object is greater, less than or equal to another.
#### Arguments
1. `x` *(Any)*: The first value to compare
2. `y` *(Any)*: The second value to compare
#### Returns
*(Number)*: Returns `1` if `x` is greater than `y`, `-1` if `y` is greater than `x`, and `0` if the objects are equal.
#### Example
```js
var comparer = Rx.helpers.defaultSubcomparer;
// Should return 0
var x = 42, y = 42
console.log(comparer(x, y));
// => 0
// Should return -1
var x = new Date(0), y = new Date();
console.log(comparer(x, y));
// => -1
// Should return 1
var x = 43, y = 42;
console.log(comparer(x, y));
// => 1
```
* * *
### `Rx.helpers.defaultError(err)`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
Throws the specified error
#### Arguments
1. `err` *(Any)*: The error to throw
#### Example
```js
var defaultError = Rx.helpers.defaultError;
// Returns its value
defaultError(new Error('woops'))
// => Error: woops
```
* * *
### `Rx.helpers.identity(x)`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
A function which returns its value unmodified.
#### Arguments
1. `x` *(Any)*: The value to return.
#### Returns
*(Any)*: The value given as the parameter.
#### Example
```js
var identity = Rx.helpers.identity;
// Returns its value
var x = identity(42);
console.log(x);
// => 42
```
* * *
### `Rx.helpers.isPromise(p)`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
A function which determines whether the object is a `Promise`.
#### Arguments
1. `p` *(Any)*: The object to determine whether it is a promise.
#### Returns
*(Boolean)*: `true` if the object is a `Promise` else `false`
#### Example
```js
var isPromise = Rx.helpers.isPromise;
var p = RSVP.Promise(function (res) { res(42); });
console.log(isPromise(p));
// => true
```
* * *
### `Rx.helpers.noop()`
#[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/basicheader.js "View in source") [Ⓣ][1]
A function which does nothing
#### Example
```js
var noop = Rx.helpers.noop;
// This does nothing!
noop();
```
* * *
================================================
FILE: doc/api/schedulers/historicalscheduler.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
### `Rx.HistoricalScheduler` class
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/historicalscheduler.js "View in source")
Provides a virtual time scheduler that uses an optional `Date` for absolute time and time spans for relative time. This inherits from the `Rx.VirtualTimeScheduler` class.
## Usage ##
The following shows an example of using the `Rx.HistoricalScheduler`. This shows creating a minute's worth of data from January 1st, 1970.
```js
// Initial data
var initialDate = 0;
var scheduler = new Rx.HistoricalScheduler(new Date(initialDate));
// Yield unto this subject
var s = new Rx.Subject();
// Some random data
function getData(time) {
return Math.floor(Math.random() * (time + 1));
}
// Enqueue 1 minute's worth of data
while (initialDate <= 60000) {
(function (i) {
scheduler.scheduleFuture(new Date(i), function () {
s.onNext({ value: getData(i), date: new Date(i) });
});
}(initialDate));
initialDate += 10000;
}
// Subscription set
s.subscribe(function (x) {
console.log('value: ', x.value);
console.log('date: ', x.date.toGMTString());
});
// Run it
scheduler.start();
// => value: 0
// => date: Thu, 1 Jan 1970 00:00:00 UTC
// => value: 2013
// => date: Thu, 1 Jan 1970 00:00:10 UTC
// => value: 5896
// => date: Thu, 1 Jan 1970 00:00:20 UTC
// => value: 5415
// => date: Thu, 1 Jan 1970 00:00:30 UTC
// => value: 13411
// => date: Thu, 1 Jan 1970 00:00:40 UTC
// => value: 15518
// => date: Thu, 1 Jan 1970 00:00:50 UTC
// => value: 51076
// => date: Thu, 1 Jan 1970 00:01:00 UTC
```
### Location
File:
- [`/src/core/concurrency/historicalscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/historicalscheduler.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
- [`rx.virutaltime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.virutaltime.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-VirtualTime`](http://www.nuget.org/packages/RxJS-VirtualTime/)
Unit Tests:
- [`/tests/concurrency/historicalscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/tests/observable/historicalscheduler.js)
## `HistoricalScheduler Constructor` ##
- [`constructor`](#rxhistoricalschedulerinitialclock-comparer)
## Inherited Classes ##
- [`Rx.VirtualScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/virtualtimescheduler.md)
## _HistoricalScheduler Constructor_ ##
### `Rx.HistoricalScheduler([initialClock], [comparer])`
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/historicalscheduler.js "View in source")
Creates a new historical scheduler with the specified initial clock value.
#### Arguments
1. [`initialClock`] *(Function)*: Initial value for the clock.
2. [`comparer`] *(Function)*: Comparer to determine causality of events based on absolute time.
#### Example
```js
function comparer (x, y) {
if (x > y) { return 1; }
if (x < y) { return -1; }
return 0;
}
var scheduler = new Rx.HistoricalScheduler(
new Date(0), /* initial clock of 0 */
comparer /* comparer for determining order */
);
```
================================================
FILE: doc/api/schedulers/scheduler.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.Scheduler` class #
Provides a set of static methods to access commonly used schedulers and a base class for all schedulers.
## Usage ##
The follow example shows the basic usage of an `Rx.Scheduler`.
```js
var disposable = Rx.Scheduler.default.schedule(
'world',
function (scheduler, x) { console.log('hello ' + x); }
);
// => hello world
```
### Location
File:
- [`scheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.js)
- [`scheduler.periodic.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.periodic.js)
- [`scheduler.recursive.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.recursive.js)
- [`scheduler.wrappers.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.wrappers.js)
- [`currentthreadscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/currentthreadscheduler.js)
- [`defaultscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/defaultscheduler.js)
- [`immediatescheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/immediatescheduler.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
## `Scheduler Instance Methods` ##
- [`catch`](#rxschedulerprototypecatchhandler)
- [`now`](#rxschedulerprototypenow)
### Standard Scheduling ###
- [`schedule`](#rxschedulerprototypeschedulestate-action)
- [`scheduleFuture`](#rxschedulerprototypeschedulefuturestate-duetime-action)
### Recursive Scheduling ###
- [`scheduleRecursive`](#rxschedulerprototypeschedulerecursivestate-action)
- [`scheduleRecursiveFuture`](#rxschedulerprototypeschedulerecursivefuturestate-duetime-action)
### Periodic Scheduling ###
- [`schedulePeriodic`](#rxschedulerscheduleperiodicstate-period-action)
## `Scheduler` Class Methods ##
- [`normalize`](#rxschedulernormalizetimespan)
- [`isScheduler`](#rxschedulerisschedulerobj)
## `Scheduler` Class Properties ##
- [`currentThread`](#rxschedulercurrentthread)
- [`immediate`](#rxschedulerimmediate)
- [`default` | `async`](#rxschedulerdefault)
## _Scheduler Instance Methods_ ##
### `Rx.Scheduler.prototype.catch(handler)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.wrappers.js "View in source")
Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
#### Arguments
1. `handler` `Function`: Handler that's run if an exception is caught. The error will be rethrown if the handler returns `false`.
#### Returns
`Scheduler`: Wrapper around the original scheduler, enforcing exception handling.
#### Example
```js
SchedulerError.prototype = Object.create(Error.prototype);
function SchedulerError(message) {
this.message = message;
Error.call(this);
}
var scheduler = Rx.Scheduler.default;
var catchScheduler = scheduler.catch(function (e) {
return e instanceof SchedulerError;
});
// Throws no exception
var d1 = catchScheduler.schedule(function () {
throw new SchedulerError('woops');
});
var d2 = catchScheduler.schedule(function () {
throw new Error('woops');
});
// => Uncaught Error: woops
```
***
### `Rx.Scheduler.prototype.now()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.js "View in source")
Gets the current time according to the Scheduler implementation.
#### Returns
`Number`: The current time according to the Scheduler implementation.
#### Example
```js
var now = Rx.Scheduler.default.now();
console.log(now);
// => 1381806323143
```
### Location
- rx.js
***
### Standard Scheduling ###
***
### `Rx.Scheduler.prototype.schedule(state, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.js "View in source")
Schedules an action to be executed with state.
#### Arguments
1. `state`: Any: State passed to the action to be executed.
2. `action`: `Function`: Action to execute with the following arguments:
1. `scheduler`: `Scheduler` - The current Scheduler
2. `state`: `Any` - The current state
#### Returns
`Disposable`: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
var disposable = Rx.Scheduler.immediate.schedule('world', function (scheduler, x) {
console.log('hello ' + x);
});
// => hello world
// Tries to cancel but too late since it is immediate
disposable.dispose();
```
***
### `Rx.Scheduler.prototype.scheduleFuture(state, dueTime, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.js "View in source")
Schedules an action to be executed at the specified relative due time. Note this only works with the built-in `Rx.Scheduler.default` scheduler, as the rest will throw an exception as the framework does not allow for blocking.
#### Arguments
1. `state` `Any`: State passed to the action to be executed.
2. `dueTime` `Number` | `Date`: Relative or absolute time at which to execute the action.
3. `action`: `Function`: Action to execute with the following arguments:
1. `scheduler`: `Scheduler` - The current Scheduler
2. `state`: `Any` - The current state
#### Returns
`Disposable`: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
/* Relative schedule */
var disposable = Rx.Scheduler.default.scheduleFuture(
'world',
5000, /* 5 seconds in the future */
function (scheduler, x) {
console.log('hello ' + x + ' after 5 seconds');
}
);
// => hello world after 5 seconds
/* Absolute schedule */
var disposable = Rx.Scheduler.default.scheduleFuture(
'world',
new Date(Date.now() + 5000), /* 5 seconds in the future */
function (scheduler, x) {
console.log('hello ' + x + ' after 5 seconds');
}
);
// => hello world after 5 seconds
```
***
### Recursive Scheduling ###
### `Rx.Scheduler.prototype.scheduleRecursive(state, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.recursive.js "View in source")
Schedules an action to be executed with state.
#### Arguments
1. `state` `Any`: State passed to the action to be executed.
2. `action`: `Function`: Action to execute with the following parameters:
1. `state`: `Any` - The state passed in
2. `recurse`: `Function` - The action to execute for recursive actions which takes the form of `recurse(newState)` where the new state is passed to be executed again.
#### Returns
`Disposable`: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
var disposable = Rx.Scheduler.default.scheduleRecursive(
0,
function (i, recurse) {
console.log(i); if (++i < 3) { recurse(i); }
}
);
// => 0
// => 1
// => 2
```
***
### `Rx.Scheduler.prototype.scheduleRecursiveFuture(state, dueTime, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.recursive.js#L114-118 "View in source")
Schedules an action to be executed recursively at a specified absolute or relative due time. Note this only works with the built-in `Rx.Scheduler.timeout` scheduler, as the rest will throw an exception as the framework does not allow for blocking.
#### Arguments
1. `state` `Any`: State passed to the action to be executed.
2. `dueTime` `Number`: Absolute time at which to execute the action for the first time.
2. `action`: `Function`: Action to execute with the following parameters:
1. `state`: `Any` - The state passed in
2. `recurse`: `Function` - The action to execute for recursive actions which takes the form of `recurse(newState, dueTime)`.
#### Returns
`Disposable`: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
/* Absolute recursive future */
var disposable = Rx.Scheduler.default.scheduleRecursiveFuture(
0,
new Date(Date.now() + 5000), /* 5 seconds in the future */
function (i, self) {
console.log(i);
if (++i < 3) {
// Schedule mutliplied by a second by position
self(i, new Date(Date.now() + (i * 1000)));
}
}
);
// => 0
// => 1
// => 2
/* Relative recursive future */
var disposable = Rx.Scheduler.default.scheduleRecursiveFuture(
0,
5000, /* 5 seconds in the future */
function (i, self) {
console.log(i);
if (++i < 3) {
// Schedule mutliplied by a second by position
self(i, i * 1000);
}
}
);
// => 0
// => 1
// => 2
```
***
### Periodic Scheduling ###
### `Rx.Scheduler.prototype.schedulePeriodic(state, period, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.periodic.js#L20-31 "View in source")
Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using `window.setInterval` for the base implementation.
#### Arguments
1. `state` `Any`: State passed to the action to be executed.
2. `period` `Number`: Period for running the work periodically in ms.
3. `action`: `Function`: Action to execute with the following parameters. Note that the return value from this function becomes the state in the next execution of the action.
1. `state`: `Any` - The state passed in
#### Returns
`Disposable`: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
var disposable = Rx.Scheduler.default.schedulePeriodic(
0,
1000, /* 1 second */
function (i) {
console.log(i);
// After three times, dispose
if (++i > 3) { disposable.dispose(); }
return i;
});
// => 0
// => 1
// => 2
// => 3
```
***
## _Scheduler Class Methods_ ##
### `Rx.Scheduler.normalize(timeSpan)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.js#L87-90 "View in source")
Normalizes the specified time span value to a positive value.
#### Arguments
1. `timeSpan` `Number`: The time span value to normalize.
#### Returns
`Number`: The specified time span value if it is zero or positive; otherwise, 0
#### Example
```js
var r1 = Rx.Scheduler.normalize(-1);
console.log(r1);
// => 0
var r2 = Rx.Scheduler.normalize(255);
console.log(r2);
// => 255
```
***
### `Rx.Scheduler.isScheduler(obj)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/scheduler.js "View in source")
Determines whether the given object is a `Scheduler` instance
#### Arguments
1. `obj` `Any`: The object to determine whether it is a `Scheduler` instance
#### Returns
`Boolean`: Whether the given object is a Scheduler.
#### Example
```js
var isScheduler = Rx.Scheduler.isScheduler(Rx.Scheduler.default);
console.log('Is scheduler? %s', isScheduler);
// Is scheduler? true
```
***
## _Scheduler Class Properties_ ##
### `Rx.Scheduler.currentThread`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/currentthreadscheduler.js "View in source")
Gets a scheduler that schedules work as soon as possible on the current thread. This implementation does not support relative and absolute scheduling due to thread blocking required.
#### Example
```js
var scheduler = Rx.Scheduler.currentThread;
var disposable = scheduler.schedule(
'world',
function (scheduler, x) {
console.log('hello ' + x);
});
// => hello world
```
### Location
- rx.js
***
### `Rx.Scheduler.immediate`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/immediatescheduler.js "View in source")
Gets a scheduler that schedules work immediately on the current thread.
#### Example
```js
var scheduler = Rx.Scheduler.immediate;
var disposable = scheduler.scheduleRecursive(
0,
function (x, self) {
console.log(x);
if (++x < 3) { self(x); }
}
);
// => 0
// => 1
// => 2
```
### Location
- rx.js
***
### `Rx.Scheduler.default`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/defaultscheduler.js "View in source")
Gets a scheduler that schedules work via a timed callback based upon platform. An alias exists as `Rx.Scheduler.async`.
For all schedule calls, it defaults to:
- Node.js: uses `setImmediate` for newer builds, and `process.nextTick` for older versions.
- Browser: depending on platform may use `setImmediate`, `MessageChannel`, `window.postMessage` and for older versions of IE, it will default to `script.onreadystatechanged`, else falls back to `window.setTimeout`.
For all relative and absolute scheduling, it defaults to using `window.setTimeout`.
#### Example
```js
var scheduler = Rx.Scheduler.default;
var disposable = scheduler.schedule(
0,
function (scheduler, x) {
console.log(x);
}
);
// => 0
```
***
================================================
FILE: doc/api/schedulers/virtualtimescheduler.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.VirtualTimeScheduler` class #
Base class for providing scheduling in virtual time. This inherits from the `Rx.Scheduler` class.
## Usage ##
The following shows an example of using the `Rx.VirtualTimeScheduler`. In order for this to work, you must implement the `add`, `toAbsoluteTime` and `toRelativeTime` methods as described below.
```js
/* Comparer required for scheduling priority */
function comparer (x, y) {
if (x > y) { return 1; }
if (x < y) { return -1; }
return 0;
}
var scheduler = new Rx.VirtualTimeScheduler(0, comparer);
/**
* Adds a relative time value to an absolute time value.
* @param {Any} absolute Absolute virtual time value.
* @param {Any} relative Relative virtual time value to add.
* @return {Any} Resulting absolute virtual time sum value.
*/
scheduler.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts an absolute time to a number
* @param {Number} The absolute time in ms
* @returns {Number} The absolute time in ms
*/
scheduler.toAbsoluteTime = function (absolute) {
return new Date(absolute);
};
/**
* Converts the time span number/Date to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
scheduler.toRelativeTime = function (timeSpan) {
return timeSpan;
};
// Schedule some time
scheduler.scheduleAbsolute(null, new Date(1), function () { console.log('foo'); });
scheduler.scheduleAbsolute(null, new Date(2), function () { console.log('bar'); });
scheduler.scheduleAbsolute(null, new Date(3), function () { scheduler.stop(); });
// Start the scheduler
scheduler.start();
// => foo
// => bar
// Check the clock once stopped
console.log(scheduler.now());
// => 3
console.log(scheduler.clock);
// => 3
```
### Location
File:
- [`virtualtimescheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js)
Dist:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.virtualtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.virtualtime.js)
## `VirtualTimeScheduler Constructor` ##
- [`constructor`](#rxvirtualtimeschedulerinitialclock-comparer)
## `VirtualTimeScheduler Instance Methods` ##
- [`advanceBy`](#rxvirtualtimeschedulerprototypeadvancebytime)
- [`advanceTo`](#rxvirtualtimeschedulerprototypeadvancetotime)
- [`scheduleAbsolute`](#rxvirtualtimeschedulerprototypescheduleabsolutestate-duetime-action)
- [`scheduleRelative`](#rxvirtualtimeschedulerprototypeschedulerelativestate-duetime-action)
- [`sleep`](#rxvirtualtimeschedulerprototypesleeptime)
- [`start`](#rxvritualtimeschedulerprototypestart)
- [`stop`](#rxvritualtimeschedulerprototypestop)
## `VirtualTimeScheduler Instance Properties` ##
- [`isEnabled`](#isenabled)
## `VirtualTimeScheduler Protected Abstract Methods` ##
- [`add`](#rxvirtualtimeschedulerprototypeaddabsolute-relative)
- [`toAbsoluteTime`](#rxvirtualtimeschedulerprototypetoabsolutetimeabsolute)
- [`toRelativeTime`](#rxvirtualtimeschedulerprototypetorelativetimetimespan)
## `VirtualTimeScheduler Protected Methods` ##
- [`getNext`](#rxvirtualtimeschedulerprototypegetnext)
## Inherited Classes ##
- [`Rx.Scheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/scheduler.md)
## _VirtualTimeScheduler Constructor_ ##
### `Rx.VirtualTimeScheduler(initialClock, comparer)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js#L38-L44 "View in source")
Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
#### Arguments
1. `initialClock` *(Function)*: Initial value for the clock.
2. `comparer` *(Function)*: Comparer to determine causality of events based on absolute time.
#### Example
```js
function comparer (x, y) {
if (x > y) { return 1; }
if (x < y) { return -1; }
return 0;
}
var scheduler = new Rx.VirtualTimeScheduler(
0, /* initial clock of 0 */
comparer /* comparer for determining order */
);
```
***
## _VirtualTimeScheduler Instance Methods_ ##
### `Rx.VirtualTimeScheduler.prototype.advanceBy(time)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js#L166-L176 "View in source")
Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
#### Arguments
1. `time` *(Any)*: Relative time to advance the scheduler's clock by.
#### Example
```js
var scheduler = new MyVirtualScheduler(
200 /* initial time */
);
scheduler.scheduleAbsolute(null, 250, function () {
console.log('hello');
});
scheduler.advanceBy(300);
// => hello
console.log(scheduler.clock);
// => 500
```
***
### `Rx.VirtualTimeScheduler.prototype.advanceTo(time)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js "View in source")
Advances the scheduler's clock to the specified time, running all work till that point.
#### Arguments
1. `time` *(Any)*: Absolute time to advance the scheduler's clock to.
#### Example
```js
var scheduler = new MyVirtualScheduler(
0 /* initial time */
);
scheduler.scheduleAbsolute(null, 100, function () {
console.log('hello');
});
scheduler.scheduleAbsolute(null, 200, function () {
console.log('world');
});
scheduler.advanceBy(300);
// => hello
// => world
console.log(scheduler.clock);
// => 300
```
***
### `Rx.VirtualTimeScheduler.prototype.scheduleAbsolute(state, dueTime, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js "View in source")
Schedules an action to be executed at dueTime.
#### Arguments
1. `state`: *(Any)*: State passed to the action to be executed.
2. `dueTime` *(Any)*: Absolute time at which to execute the action.
3. `action`: `Function`: Action to execute with the following arguments:
1. `scheduler`: `Scheduler` - The current Scheduler
2. `state`: `Any` - The current state
#### Returns
*(Disposable)*: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
var scheduler = new MyVirtualScheduler(
0 /* initial time */
);
scheduler.scheduleAbsolute('world', 100, function (scheduler, state) {
console.log('hello ' + state);
});
scheduler.scheduleAbsolute('moon', 200, function (scheduler, state) {
console.log('goodnight ' + state);
});
scheduler.start();
// => hello world
// => goodnight moon
console.log(scheduler.clock);
// => 200
```
***
### `Rx.VirtualTimeScheduler.prototype.scheduleRelative(state, dueTime, action)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js#L89-L92 "View in source")
Schedules an action to be executed at dueTime.
#### Arguments
1. `state`: *(Any)*: State passed to the action to be executed.
2. `dueTime` *(Any)*: Relative time after which to execute the action.
3. `action`: `Function`: Action to execute with the following arguments:
1. `scheduler`: `Scheduler` - The current Scheduler
2. `state`: `Any` - The current state
#### Returns
*(Disposable)*: The disposable object used to cancel the scheduled action (best effort).
#### Example
```js
var scheduler = new MyVirtualScheduler(
0 /* initial time */
);
scheduler.scheduleRelative('world', 100, function (scheduler, state) {
console.log('hello ' + state);
});
scheduler.scheduleRelative('moon', 200, function (scheduler, state) {
console.log('goodnight ' + state);
});
scheduler.start();
// => hello world
// => goodnight moon
console.log(scheduler.clock);
// => 300
```
***
### `Rx.VirtualTimeScheduler.prototype.sleep(time)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js#L182-L190 "View in source")
Advances the scheduler's clock by the specified relative time.
#### Arguments
1. `time` *(Any)*: Relative time to advance the scheduler's clock by.
#### Example
```js
var scheduler = new MyVirtualScheduler(
0 /* initial time */
);
scheduler.sleep(400);
console.log(scheduler.clock);
// => 400
```
***
### `Rx.VirtualTimeScheduler.prototype.start()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js#L107-L123 "View in source")
Starts the virtual time scheduler.
#### Example
```js
var scheduler = new MyVirtualScheduler(
0 /* initial time */
);
scheduler.scheduleRelative('world', 100, function (scheduler, state) {
console.log('hello ' + state);
});
scheduler.scheduleRelative('moon', 200, function (scheduler, state) {
console.log('goodnight ' + state);
});
scheduler.start();
// => hello world
// => goodnight moon
console.log(scheduler.clock);
// => 400
```
***
### `Rx.VirtualTimeScheduler.prototype.stop()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/concurrency/virtualtimescheduler.js#L128-L130 "View in source")
Stops the virtual time scheduler.
#### Example
```js
var scheduler = new MyVirtualScheduler(
0 /* initial time */
);
scheduler.scheduleRelative('world', 100, function (scheduler, state) {
console.log('hello ' + state);
});
scheduler.scheduleRelative(null, 100, function (scheduler, state) {
scheduler.stop();
});
scheduler.scheduleRelative(null, 100, function (scheduler, state) {
console.log('goodbye cruel ' + state);
});
scheduler.start();
// => hello world
```
***
## _VirtualTimeScheduler Abstract Protected Methods_ ##
### `Rx.VirtualTimeScheduler.prototype.add(absolute, relative)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/asyncsubject.js#L54 "View in source")
Adds a relative time value to an absolute time value. This method is used in several methods including `scheduleRelative`, `advanceBy` and `sleep`.
### Arguments
1. `absolute` *(Any)*: Absolute virtual time value.
2. `relative` *(Any)*: Relative virtual time value.
#### Returns
*(Any)*: Resulting absolute virtual time sum value.
#### Example
One possible implementation could be as simple as the following:
```js
scheduler.add = function (absolute, relative) {
return absolute + relative;
};
```
***
### `Rx.VirtualTimeScheduler.prototype.toAbsoluteTime(absolute)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/asyncsubject.js#L61 "View in source")
Converts an absolute time to a number. This is used directly in the `now` method on the `Rx.Scheduler`
### Arguments
1. `absolute` *(Any)*: The absolute time to convert.
#### Returns
*(Number)*: The absolute time in ms.
#### Example
One possible implementation could be as simple as the following:
```js
// String -> Number
scheduler.toAbsoluteTime = function (absolute) {
return absolute.length;
};
```
***
### `Rx.VirtualTimeScheduler.prototype.toRelativeTime(timeSpan)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/asyncsubject.js#L61 "View in source")
Converts the time span number/Date to a relative virtual time value.
### Arguments
1. `timeSpan` *(Any)*: The time span number value to convert. This is used directly in `scheduleFuture`.
#### Returns
*(Number)*: Corresponding relative virtual time value.
#### Example
One possible implementation could be as simple as the following:
```js
// Number -> Number
scheduler.toRelativeTime = function (timeSpan) {
return timeSpan;
};
```
***
================================================
FILE: doc/api/subjects/asyncsubject.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.AsyncSubject` class #
Represents the result of an asynchronous operation. The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
This class inherits both from the `Rx.Observable` and `Rx.Observer` classes.
## Usage ##
The following example shows caching on the last value produced when followed by an onCompleted notification which makes it available to all subscribers.
```js
var subject = new Rx.AsyncSubject();
var i = 0;
var handle = setInterval(function () {
subject.onNext(i);
if (++i > 3) {
subject.onCompleted();
clearInterval(handle);
}
}, 500);
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 3
// => Completed
```
### Location
- rx.js
## `AsyncSubject Constructor` ##
- [`constructor`](#rxasyncsubject)
## `AsyncSubject Instance Methods` ##
- [`dispose`](#rxasyncsubjectprototypedispose)
- [`hasObservers`](#rxasyncsubjectprototypehasobservers)
## Inherited Classes ##
- [`Rx.Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
- [`Rx.Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md)
## _AsyncSubject Constructor_ ##
### `Rx.AsyncSubject()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/asyncsubject.js#L33-L41 "View in source")
Creates a subject that can only receive one value and that value is cached for all future observations.
#### Example
```js
var subject = new Rx.AsyncSubject();
subject.onNext(42);
subject.onCompleted();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
// => Completed
```
### Location
- rx.js
* * *
## _AsyncSubject Instance Methods_ ##
### `Rx.AsyncSubject.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/asyncsubject.js#L108-L113 "View in source")
Unsubscribe all observers and release resources.
#### Example
```js
var subject = new Rx.AsyncSubject();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
subject.onCompleted();
// => Next: 42
// => Completed
subject.dispose();
try {
subject.onNext(56);
} catch (e) {
console.log(e.message);
}
// => Object has been disposed
```
### Location
- rx.js
* * *
### `Rx.AsyncSubject.prototype.hasObservers()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/asyncsubject.js#L48-L51 "View in source")
Indicates whether the subject has observers subscribed to it.
#### Returns
*(Boolean)*: Returns `true` if the AsyncSubject has observers, else `false`.
#### Example
```js
var subject = new Rx.AsyncSubject();
console.log(subject.hasObservers());
// => false
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
console.log(subject.hasObservers());
// => true
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/subjects/behaviorsubject.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.BehaviorSubject` class #
Represents a value that changes over time. Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications. If you are looking for BehaviorSubject without initial value see [`Rx.ReplaySubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/replaysubject.md).
This class inherits both from the `Rx.Observable` and `Rx.Observer` classes.
## Usage ##
The follow example shows the basic usage of an `Rx.BehaviorSubject` class.
```js
/* Initialize with initial value of 42 */
var subject = new Rx.BehaviorSubject(42);
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 42
subject.onNext(56);
// => Next: 56
subject.onCompleted();
// => Completed
```
### Location
- rx.binding.js
## `BehaviorSubject Constructor` ##
- [`constructor`](#rxbehaviorsubjectintialvalue)
## `BehaviorSubject Instance Methods` ##
- [`dispose`](#rxbehaviorsubjectprototypedispose)
- [`getValue`](#rxbehaviorsubjectprototypegetvalue)
- [`hasObservers`](#rxbehaviorsubjectprototypehasobservers)
## Inherited Classes ##
- [`Rx.Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
- [`Rx.Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md)
## _BehaviorSubject Constructor_ ##
### `Rx.BehaviorSubject(initialValue)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/behaviorsubject.js#L27-L34 "View in source")
Initializes a new instance of the `Rx.BehaviorSubject` class which creates a subject that caches its last value and starts with the specified value.
#### Arguments
1. `initialValue` *(Any)*: Initial value sent to observers when no other value has been received by the subject yet.
#### Example
```js
var subject = new Rx.BehaviorSubject(56);
subject.onCompleted();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: 56
subject.onNext(42);
// => Next: 42
subject.onCompleted();
// => Completed
```
### Location
= rx.binding.js
* * *
## _BehaviorSubject Instance Methods_ ##
### `Rx.BehaviorSubject.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/behaviorsubject.js#L101-L106 "View in source")
Unsubscribe all observers and release resources.
#### Example
```js
var subject = new Rx.BehaviorSubject();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
// => Next: 42
subject.onCompleted();
// => Completed
subject.dispose();
try {
subject.onNext(56);
} catch (e) {
console.log(e.message);
}
// => Object has been disposed
```
### Location
= rx.binding.js
* * *
### `Rx.BehaviorSubject.prototype.getValue()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/behaviorsubject.js#L44-L50 "View in source")
Gets the current value or throws an exception.
Value is frozen after `onCompleted` is called.
After `onError` is called always throws the specified exception.
An exception is always thrown after `dispose` is called.
#### Returns
*(Mixed)*: The initial `value` passed to the constructor until `onNext` is called; after which, the last value passed to `onNext`.
#### Example
```js
var subject = new Rx.BehaviorSubject(56);
console.log('Value is: ' + subject.getValue());
// => Value is: 56
subject.onNext(42);
console.log('Value is: ' + subject.getValue());
// => Value is: 42
subject.onCompleted();
subject.onNext(100);
console.log('Value is frozen: ' + subject.getValue());
// => Value is frozen: 42
subject.dispose();
try {
subject.getValue();
} catch (e) {
console.log(e.message);
}
// => Object has been disposed
```
### Location
= rx.binding.js
* * *
### `Rx.BehaviorSubject.prototype.hasObservers()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/behaviorsubject.js#L55 "View in source")
Indicates whether the subject has observers subscribed to it.
#### Returns
*(Boolean)*: Returns `true` if the Subject has observers, else `false`.
#### Example
```js
var subject = new Rx.BehaviorSubject();
console.log(subject.hasObservers());
// => false
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
console.log(subject.hasObservers());
// => true
```
### Location
= rx.binding.js
* * *
================================================
FILE: doc/api/subjects/replaysubject.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.ReplaySubject` class #
Represents an object that is both an observable sequence as well as an observer. Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
This class inherits both from the `Rx.Observable` and `Rx.Observer` classes.
## Usage ##
The follow example shows the basic usage of an `Rx.ReplaySubject` class. Note that this only holds the past two items in the cache.
```js
var subject = new Rx.ReplaySubject(2 /* buffer size */);
subject.onNext('a');
subject.onNext('b');
subject.onNext('c');
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: b
// => Next: c
subject.onNext('d');
// => Next: d
```
### Location
- rx.binding.js
## `ReplaySubject Constructor` ##
- [`constructor`](#rx)
## `ReplaySubject Instance Methods` ##
- [`dispose`](#rxreplaysubjectprototypedispose)
- [`hasObservers`](#rxreplaysubjectprototypehasobservers)
## Inherited Classes ##
- [`Rx.Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
- [`Rx.Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md)
## _ReplaySubject Constructor_ ##
### `Rx.ReplaySubject([bufferSize], [windowSize], [scheduler])`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/replaysubject.js#L53-L64 "View in source")
Initializes a new instance of the `Rx.ReplaySubject` class with the specified buffer size, window and scheduler.
#### Arguments
1. `[bufferSize = Number.MAX_VALUE]` *(Number)*: Maximum element count of the replay buffer.
2. `[windowSize = NUMBER.MAX_VALUE]` *(Number)*: Maximum time length of the replay buffer.
3. `[scheduler = Rx.Scheduler.currentThread]` *(Scheduler)*: Scheduler the observers are invoked on.
#### Example
```js
var subject = new Rx.ReplaySubject(
2 /* buffer size */,
null /* unlimited time buffer */,
Rx.Scheduler.timeout);
subject.onNext('a');
subject.onNext('b');
subject.onNext('c');
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: b
// => Next: c
subject.onNext('d');
// => Next: d
```
### Location
- rx.binding.js
* * *
## _ReplaySubject Instance Methods_ ##
### `Rx.ReplaySubject.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/replaysubject.js#L130-L133 "View in source")
Unsubscribe all observers and release resources.
#### Example
```js
var subject = new Rx.ReplaySubject();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
// => Next: 42
subject.onCompleted();
// => Completed
subject.dispose();
try {
subject.onNext(56);
} catch (e) {
console.log(e.message);
}
// => Object has been disposed
```
### Location
- rx.binding.js
* * *
### `Rx.ReplaySubject.prototype.hasObservers()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/replaysubject.js#L61-L63 "View in source")
Indicates whether the subject has observers subscribed to it.
#### Returns
*(Boolean)*: Returns `true` if the Subject has observers, else `false`.
#### Example
```js
var subject = new Rx.ReplaySubject();
console.log(subject.hasObservers());
// => false
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
console.log(subject.hasObservers());
// => true
```
### Location
- rx.binding.js
* * *
================================================
FILE: doc/api/subjects/subject.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.Subject` class #
Represents an object that is both an observable sequence as well as an observer. Each notification is broadcasted to all subscribed observers.
This class inherits both from the `Rx.Observable` and `Rx.Observer` classes.
## Usage ##
The following example shows the basic usage of an Rx.Subject.
```js
var subject = new Rx.Subject();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
// => Next: 42
subject.onNext(56);
// => Next: 56
subject.onCompleted();
// => Completed
```
### Location
- rx.js
## `Subject Constructor` ##
- [`constructor`](#rxsubject)
## `Subject Class Methods` ##
- [`create`](#rxsubjectcreateobserver-observable)
## `Subject Instance Methods` ##
- [`dispose`](#rxsubjectprototypedispose)
- [`hasObservers`](#rxsubjectprototypehasobservers)
## Inherited Classes ##
- [`Rx.Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
- [`Rx.Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md)
## _Subject Constructor_ ##
### `Rx.Subject()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/subject.js#L26-L31 "View in source")
Creates a subject.
#### Example
```js
var subject = new Rx.Subject();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
// => Next: 42
subject.onCompleted();
// => Completed
```
### Location
- rx.js
* * *
## _Subject Class Methods_ ##
### `Rx.Subject.create(observer, observable)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/subject.js#L101-L103 "View in source")
Creates a subject from the specified observer and observable.
#### Arguments
1. `observer` *(Observer)*: The observer used to send messages to the subject.
2. `observable` *(Observable)*: The observable used to subscribe to messages sent from the subject.
#### Returns
*(Subject)*: Subject implemented using the given observer and observable.
#### Example
```js
/* Using a Web Worker to send and receive data via an Rx.Subject */
/* worker.js */
self.onmessage = function(e) {
self.postMessage(e.data);
};
/* client.js */
var worker = new Worker('worker.js');
// Create observer to handle sending messages
var observer = Rx.Observer.create(
function (data) {
worker.postMessage(data);
});
// Create observable to handle the messages
var observable = Rx.Observable.create(function (obs) {
worker.onmessage = function (data) {
obs.onNext(data);
};
worker.onerror = function (err) {
obs.onError(err);
};
return function () {
worker.close();
};
});
var subject = Rx.Subject.create(observer, observable);
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
// => Next: 42
```
### Location
- rx.js
* * *
## _Subject Instance Methods_ ##
### `Rx.Subject.prototype.dispose()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/subject.js#L89-L92 "View in source")
Unsubscribe all observers and release resources.
#### Example
```js
var subject = new Rx.Subject();
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
subject.onNext(42);
// => Next: 42
subject.onCompleted();
// => Completed
subject.dispose();
try {
subject.onNext(56);
} catch (e) {
console.log(e.message);
}
// => Object has been disposed
```
### Location
- rx.js
* * *
### `Rx.Subject.prototype.hasObservers()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/subjects/subject.js#L38-L40 "View in source")
Indicates whether the subject has observers subscribed to it.
#### Returns
*(Boolean)*: Returns `true` if the Subject has observers, else `false`.
#### Example
```js
var subject = new Rx.Subject();
console.log(subject.hasObservers());
// => false
var subscription = subject.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
console.log(subject.hasObservers());
// => true
```
### Location
- rx.js
* * *
================================================
FILE: doc/api/testing/reactivetest.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.ReactiveTest` class #
This class contains test utility methods such as create notifications for testing purposes.
### Location
- rx.testing.js
## `ReactiveTest Class Methods` ##
- [`onCompleted`](#rxreactivetestoncompletedticks)
- [`onError`](#rxreactivetestonerrorticksexception)
- [`onNext`](#rxreactivetestonnextticksvalue)
- [`subscribe`](#rxasyncsubjectprototypehasobservers)
## `ReactiveTest Class Fields` ##
- [`created`](#rxreactivetestcreated)
- [`disposed`](#rxreactivetestdisposed)
- [`subscribed`](#rxreactivetestsubscribed)
## _ReactiveTest Class Methods_ ##
### `Rx.ReactiveTest.onCompleted(ticks)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/reactivetest.js#L89-L91 "View in source")
Factory method for an OnCompleted notification record at a given time.
#### Arguments
1. `ticks` *(Number)*: Recorded virtual time the OnCompleted notification occurs.
#### Returns
*(Recorded)*: OnCompleted notification.
#### Example
```js
var onCompleted = Rx.ReactiveTest.onCompleted;
var scheduler = new Rx.TestScheduler();
var xs = scheduler.createHotObservable(
onCompleted(260)
);
var res = scheduler.startScheduler(function () {
return xs.map(function (x) { return x; });
});
// Write custom assertion
collectionAssert.assertEqual(res.messages, [
onCompleted(260)
]);
```
### Location
- rx.testing.js
* * *
### `Rx.ReactiveTest.onError(ticks, exception)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/reactivetest.js#L77-L82 "View in source")
Factory method for an OnError notification record at a given time with a given error.
#### Arguments
1. `ticks` *(Number)*: Recorded virtual time the OnError notification occurs.
2. `exception` *(Error | Function)*: Recorded exception stored in the OnError notification or a predicate
#### Returns
*(Recorded)*: Recorded OnError notification.
#### Example
```js
var ex = new Error('woops');
var onError = Rx.ReactiveTest.onError;
var scheduler = new Rx.TestScheduler();
var xs = scheduler.createHotObservable(
onError(201, ex)
);
var res = scheduler.startScheduler(function () {
return xs.map(function (x) { return x; });
});
// Write custom assertion
collectionAssert.assertEqual(res.messages, [
// Using a predicate
onError(201, function (e) { return e.message === 'woops'; })
]);
```
### Location
- rx.testing.js
* * *
### `Rx.ReactiveTest.onNext(ticks, value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/reactivetest.js#L61-L66 "View in source")
Factory method for an OnNext notification record at a given time with a given error.
#### Arguments
1. `ticks` *(Number)*: Recorded virtual time the OnNext notification occurs.
2. `value` *(Any | Function)*: Recorded exception stored in the OnNext notification or a predicate
#### Returns
*(Recorded)*: Recorded OnNext notification.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext;
var scheduler = new Rx.TestScheduler();
var xs = scheduler.createHotObservable(
onNext(201, 42)
);
var res = scheduler.startScheduler(function () {
return xs.map(function (x) { return x; });
});
// Write custom assertion
collectionAssert.assertEqual(res.messages, [
// Using a predicate
onNext(201, function (x) { return x === 42; })
]);
```
### Location
- rx.testing.js
* * *
## _ReactiveTest Class Fields_ ##
### `Rx.ReactiveTest.created`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/reactivetest.js#L45 "View in source")
Default virtual time used for creation of observable sequences in unit tests. This has a value of `100`.
#### Example
```js
var scheduler = new Rx.TestScheduler();
var xs = scheduler.createHotObservable(
Rx.ReactiveTest.onNext(201, 42),
Rx.ReactiveTest.onNext(202, 56),
Rx.ReactiveTest.onCompleted(203)
);
var res = scheduler.startScheduler(
function () { return xs.map(function (x) { return x; })},
Rx.ReactiveTest.created,
Rx.ReactiveTest.subscribed,
Rx.ReactiveTest.disposed
);
```
### Location
- rx.testing.js
* * *
### `Rx.ReactiveTest.disposed`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/reactivetest.js#L49 "View in source")
Default virtual time used to dispose subscriptions in unit tests. This has a value of `1000`.
#### Example
```js
var scheduler = new Rx.TestScheduler();
var xs = scheduler.createHotObservable(
Rx.ReactiveTest.onNext(201, 42),
Rx.ReactiveTest.onNext(202, 56),
Rx.ReactiveTest.onCompleted(203)
);
var res = scheduler.startScheduler(
function () { return xs.map(function (x) { return x; })},
{
created: Rx.ReactiveTest.created,
subscribed: Rx.ReactiveTest.subscribed,
disposed: Rx.ReactiveTest.disposed
}
);
```
### Location
- rx.testing.js
* * *
### `Rx.ReactiveTest.subscribed`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/reactivetest.js#L47 "View in source")
Default virtual time used to subscribe to observable sequences in unit tests. This has a value of `200`.
#### Example
```js
var scheduler = new Rx.TestScheduler();
var xs = scheduler.createHotObservable(
Rx.ReactiveTest.onNext(201, 42),
Rx.ReactiveTest.onNext(202, 56),
Rx.ReactiveTest.onCompleted(203)
);
var res = scheduler.startScheduler(
function () { return xs.map(function (x) { return x; })}
);
```
### Location
- rx.testing.js
* * *
================================================
FILE: doc/api/testing/recorded.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.Recorded` class #
Record of a value including the virtual time it was produced on.
### Location
- rx.testing.js
## `Recorded Constructor` ##
- [`constructor`](#rxrecordedtime-value-comparer)
## `Recorded Instance Methods` ##
- [`equals`](#rxrecordedprototypeequalsother)
- [`toString`](#rxrecordedprototypetostring)
## `Recorded Instance Properties` ##
- [`time`](#time)
- [`value`](#value)
## _Recorded Constructor_ ##
### `Rx.Recorded(time, value, [comparer])`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/recorded.js#L9-L13 "View in source")
Creates a new object recording the production of the specified value at the given virtual time.
#### Arguments
1. `time` *(Number)*: Virtual time the value was produced on.
2. `value` *(Any)*: Value that was produced
3. `[comparer]` *(Function)*: Optional comparer function.
#### Example
```js
var recorded = new Rx.Recorded(200, 'value');
console.log(recorded.time);
// => 200
console.log(recorded.value);
// => value
```
### Location
- rx.js
* * *
## _Recorded Instance Methods_ ##
### `Rx.Recorded.prototype.equals(other)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/recorded.js#L21-L23 "View in source")
Checks whether the given recorded object is equal to the current instance.
#### Arguments
1. `other` *(Recorded)*: Recorded object to check for equality.
#### Returns
*(Boolean)*: Returns `true` if the Recorded equals the other, else `false`.
#### Example
```js
var r1 = new Recorded(201, 'foo');
var r2 = new Recorded(201, 'bar');
var r3 = new Recorded(201, 'foo');
console.log(r1.equals(r2));
// => false
console.log(r1.equals(r3));
// => true
```
### Location
- rx.testing.js
* * *
### `Rx.Recorded.prototype.toString()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/recorded.js#L30-L32 "View in source")
Returns a string representation of the current Recorded value.
#### Returns
*(String)*: String representation of the current Recorded value.
#### Example
```js
var r1 = new Recorded(201, 'foo');
console.log(r1.toString());
// => foo@201
```
### Location
- rx.testing.js
* * *
## _Recorded Instance Properties_ ##
### `time`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/recorded.js#L10 "View in source")
Gets the virtual time the value was produced on.
#### Returns
*(Number)*: The virtual time the value was produced on.
#### Example
```js
var r1 = new Recorded(201, 'foo');
console.log(r1.time);
// => 201
```
### Location
- rx.testing.js
* * *
### `value`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/recorded.js#L11 "View in source")
Gets the recorded value.
#### Returns
*(Number)*: The recorded value.
#### Example
```js
var r1 = new Recorded(201, 'foo');
console.log(r1.value);
// => foo
```
### Location
- rx.testing.js
* * *
================================================
FILE: doc/api/testing/subscription.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.Subscription` class #
Records information about subscriptions to and unsubscriptions from observable sequences.
### Location
- rx.testing.js
## `Subscription Constructor` ##
- [`constructor`](#rxsubscriptionsubscribe-unsubscribe)
## `Subscription Instance Methods` ##
- [`equals`](#rxsubscriptionprototypeequalsother)
- [`toString`](#rxsubscriptionprototypetostring)
## `Subscription Instance Properties` ##
- [`subscribe`](#subscribe)
- [`unsubscribe`](#unsubscribe)
## _Subscription Constructor_ ##
### `Rx.Subscription(subscribe, unsubscribe)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/subscription.js#L8-L11 "View in source")
Creates a new subscription object with the given virtual subscription and unsubscription time.
#### Arguments
1. `subscribe` *(Number)*: Virtual time at which the subscription occurred.
2. `[unsubscribe = Number.MAX_VALUE]` *(Number)*: Virtual time at which the unsubscription occurred.
#### Example
```js
var subscription = new Rx.Subscription(200, 1000);
console.log(subscription.subscribe);
// => 200
console.log(subscription.unsubscribe);
// => 1000
```
### Location
- rx.testing.js
* * *
## _Subscription Instance Methods_ ##
### `Rx.Subscription.prototype.equals(other)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/subscription.js#L18-L20 "View in source")
Checks whether the given subscription is equal to the current instance.
#### Arguments
1. `other` *(Subscription)*: Subscription object to check for equality.
#### Returns
*(Boolean)*: Returns `true` if the Subscription equals the other, else `false`.
#### Example
```js
var s1 = new Subscription(201, 500);
var s2 = new Subscription(201);
var s3 = new Subscription(201, 500);
console.log(s1.equals(s2));
// => false
console.log(s1.equals(s3));
// => true
```
### Location
- rx.testing.js
* * *
### `Rx.Subscription.prototype.toString()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/subscription.js#L30-L32 "View in source")
Returns a string representation of the current Subscription value.
#### Returns
*(String)*: String representation of the current Subscription value.
#### Example
```js
var s1 = new Subscription(201);
console.log(s1.toString());
// => (201, Infinite)
var s2 = new Subscription(201, 1000);
console.log(s2.toString());
// => (201, 1000)
```
### Location
- rx.testing.js
* * *
## _Subscription Instance Properties_ ##
### `subscribe`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/subscription.js#L8 "View in source")
Gets the subscription virtual time.
#### Returns
*(Number)*: The subscription virtual time.
#### Example
```js
var s1 = new Subscription(201);
console.log(s1.subscribe);
// => 201
```
### Location
- rx.testing.js
* * *
### `unsubscribe`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/subscription.js#L9 "View in source")
Gets the unsubscription virtual time.
#### Returns
*(Number)*: The unsubscription virtual time.
#### Example
```js
var s1 = new Subscription(201, 500);
console.log(s1.unsubscribe);
// => 500
```
### Location
- rx.testing.js
* * *
================================================
FILE: doc/api/testing/testscheduler.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# `Rx.TestScheduler` class #
Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. This inherits from the `Rx.VirtualTimeScheduler` class.
## Usage ##
The following shows an example of using the `Rx.TestScheduler`. In order to make the end comparisons work, you must implement a collection assert, for example here using QUnit.
```js
function createMessage(expected, actual) {
return 'Expected: [' + expected.toString() + ']\r\nActual: [' + actual.toString() + ']';
}
// Using QUnit testing for assertions
var collectionAssert = {
assertEqual: function (actual, expected) {
var comparer = Rx.internals.isEqual, isOk = true;
if (expected.length !== actual.length) {
ok(false, 'Not equal length. Expected: ' + expected.length + ' Actual: ' + actual.length);
return;
}
for(var i = 0, len = expected.length; i < len; i++) {
isOk = comparer(expected[i], actual[i]);
if (!isOk) {
break;
}
}
ok(isOk, createMessage(expected, actual));
}
};
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted,
subscribe = Rx.ReactiveTest.subscribe;
var scheduler = new Rx.TestScheduler();
// Create hot observable which will start firing
var xs = scheduler.createHotObservable(
onNext(150, 1),
onNext(210, 2),
onNext(220, 3),
onCompleted(230)
);
// Note we'll start at 200 for subscribe, hence missing the 150 mark
var res = scheduler.startScheduler(function () {
return xs.map(function (x) { return x * x });
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onNext(210, 4),
onNext(220, 9),
onCompleted(230)
]);
// Check for subscribe/unsubscribe
collectionAssert.assertEqual(xs.subscriptions, [
subscribe(200, 230)
]);
```
### Location
- rx.testing.js
## `TestScheduler Constructor` ##
- [`constructor`](#rxtestscheduler)
## `TestScheduler Instance Methods` ##
- [`createColdObservable`](#rxtestschedulerprototypecreatecoldobservableargs)
- [`createHotObservable`](#rxtestschedulerprototypecreatehotobservableargs)
- [`createObserver`](#rxtestschedulerprototypecreateobserver)
- [`createRejectedPromise`](#rxtestschedulerprototypecreaterejectedpromiseticks-reason)
- [`createResolvedPromise`](#rxtestschedulerprototypecreateresolvedpromiseticks-value)
- [`startScheduler`](#rxtestschedulerprototypestartschedulercreate-settings)
## Inherited Classes ##
- [`Rx.VirtualTimeScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/virtualtimescheduler.md)
## **TestScheduler Constructor** ##
### `Rx.TestScheduler()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js "View in source")
Creates a new virtual time test scheduler.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted,
subscribe = Rx.ReactiveTest.subscribe;
var scheduler = new Rx.TestScheduler();
// Create hot observable which will start firing
var xs = scheduler.createHotObservable(
onNext(150, 1),
onNext(210, 2),
onNext(220, 3),
onCompleted(230)
);
// Note we'll start at 200 for subscribe, hence missing the 150 mark
var res = scheduler.startScheduler(function () {
return xs.map(function (x) { return x * x });
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onNext(210, 4),
onNext(220, 9),
onCompleted(230)
]);
// Check for subscribe/unsubscribe
collectionAssert.assertEqual(xs.subscriptions, [
subscribe(200, 230)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
## **TestScheduler Instance Methods** ##
### `Rx.TestScheduler.prototype.createColdObservable(...args)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js#L118-L121 "View in source")
Creates a cold observable using the specified timestamped notification messages.
### Arguments
1. `args` *(Arguments)*: An arguments array of Recorded objects from `Rx.ReactiveTest.onNext`, `Rx.ReactiveTest.onError`, and `Rx.ReactiveTest.onCompleted` methods.
#### Returns
*(Observable)*: Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted
subscribe = Rx.ReactiveTest.subscribe;
var scheduler = new Rx.TestScheduler();
// Create cold observable with offset from subscribe time
var xs = scheduler.createColdObservable(
onNext(150, 1),
onNext(200, 2),
onNext(250, 3),
onCompleted(300)
);
// Note we'll start at 200 for subscribe
var res = scheduler.startScheduler(function () {
return xs.filter(function (x) { return x % 2 === 0; });
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onNext(400, 2),
onCompleted(500)
]);
// Check for subscribe/unsubscribe
collectionAssert.assertEqual(xs.subscriptions, [
subscribe(200, 500)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
### `Rx.TestScheduler.prototype.createHotObservable(...args)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js#L108-L111 "View in source")
Creates a hot observable using the specified timestamped notification messages.
### Arguments
1. `args` *(Arguments)*: An arguments array of Recorded objects from `Rx.ReactiveTest.onNext`, `Rx.ReactiveTest.onError`, and `Rx.ReactiveTest.onCompleted` methods.
#### Returns
*(Observable)*: Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted;
var scheduler = new Rx.TestScheduler();
// Create hot observable which will start firing
var xs = scheduler.createHotObservable(
onNext(150, 1),
onNext(210, 2),
onNext(220, 3),
onCompleted(230)
);
// Note we'll start at 200 for subscribe, hence missing the 150 mark
var res = scheduler.startScheduler(function () {
return xs.map(function (x) { return x * x });
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onNext(210, 4),
onNext(220, 9),
onCompleted(230)
]);
// Check for subscribe/unsubscribe
collectionAssert.assertEqual(xs.subscriptions, [
subscribe(200, 230)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
### `Rx.TestScheduler.prototype.createObserver()`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js#L127-L129 "View in source")
Creates an observer that records received notification messages and timestamps those.
#### Returns
`Observer`: Observer that can be used to assert the timing of received notifications.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext;
var scheduler = new Rx.TestScheduler();
var d = new Rx.SerialDisposable();
var xs = Rx.Observable.return(42, scheduler);
var res = scheduler.createObserver();
scheduler.scheduleAbsolute(null, 100, function () {
return d.setDisposable(xs.subscribe(
function (x) {
d.dispose();
res.onNext(x);
},
res.onError.bind(res),
res.onCompleted.bind(res)
));
});
scheduler.start();
collectionAssert.assertEqual(res.messages, [
onNext(101, 42)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
### `Rx.TestScheduler.prototype.createRejectedPromise(ticks, value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js "View in source")
Creates a rejected promise with the given reason and ticks.
### Arguments
1. `ticks` *(Number)*: The absolute time of the resolution.
2. `reason` *(Any)*: The reason for rejection to yield at the given tick.
#### Returns
*(Promise)*: A mock Promise which rejects with the given reason.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext,
onError = Rx.ReactiveTest.onError,
onCompleted = Rx.ReactiveTest.onCompleted;
var scheduler = new Rx.TestScheduler();
// Create rejected promise
var error = new Error();
var xs = scheduler.createRejectedPromise(201, error);
// Note we'll start at 200 for subscribe, hence missing the 150 mark
var res = scheduler.startScheduler(function () {
// Need to pass test scheduler due to issue #976
return Rx.Observable.fromPromise(xs, scheduler);
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onError(201, error)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
### `Rx.TestScheduler.prototype.createResolvedPromise(ticks, value)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js "View in source")
Creates a resolved promise with the given value and ticks.
### Arguments
1. `ticks` *(Number)*: The absolute time of the resolution.
2. `value` *(Any)*: The value to yield at the given tick.
#### Returns
*(Promise)*: A mock Promise which fulfills with the given value.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext,
onError = Rx.ReactiveTest.onError,
onCompleted = Rx.ReactiveTest.onCompleted;
var scheduler = new Rx.TestScheduler();
// Create resolved promise
var xs = scheduler.createResolvedPromise(201, 1);
// Note we'll start at 200 for subscribe, hence missing the 150 mark
var res = scheduler.startScheduler(function () {
// Need to pass test scheduler due to issue #976
return Rx.Observable.fromPromise(xs, scheduler);
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onNext(201, 1),
onCompleted(201)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
### `Rx.TestScheduler.prototype.startScheduler(create, settings)`
# [Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js "View in source")
Starts the test scheduler and uses the specified settings for creation, subscription and disposal. If not specified, they will be set to their default timings.
### Arguments
1. `create` : `Function` - Factory method to create an observable sequence.
2. `settings`: `Object` - An object with the following properties:
- `created`: `Number` - the time to create the Observable sequence. If not specified, will default to 100.
- `subscribed`: `Number` - the time to subscribe to the Observable sequence. If not specified, will default to 200.
- `disposed`: `Number` - the time to dispose the Observable sequence. If not specified, will default to 1000.
#### Returns
`Observer`: Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
#### Example
```js
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted;
var scheduler = new Rx.TestScheduler();
// Create cold observable with offset from subscribe time
var xs = scheduler.createColdObservable(
onNext(150, 1),
onNext(200, 2),
onNext(250, 3),
onCompleted(300)
);
// Note we'll start at 200 for subscribe
var res = scheduler.startScheduler(function () {
return xs.filter(function (x) { return x % 2 === 0; });
});
// Implement collection assertion
collectionAssert.assertEqual(res.messages, [
onNext(400, 2),
onCompleted(500)
]);
// Check for subscribe/unsubscribe
collectionAssert.assertEqual(xs.subscriptions, [
subscribe(200, 500)
]);
```
### Location
File:
- [`/src/core/testing/testscheduler.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/testing/testscheduler.js)
Dist:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.texting.js)
Prerequisites:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) |
[`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
* * *
================================================
FILE: doc/designguidelines/readme.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Design Guidelines #
1. [Introduction](#1-introduction)
2. [When to use RxJS](#2-when-to-use-rxjs)
1. [Use RxJS for orchestrating asynchronous and event-based computations](#21-use-rxjs-for-orchestrating-asynchronous-and-event-based-computations)
2. [Use RxJS to deal with asynchronous sequences of data](#22-use-rxjs-to-deal-with-asynchronous-sequences-of-data)
3. [The RxJS contract](#3-the-rxjs-contract)
1. [Assume the RxJS Grammar](#31-the-rxjs-grammar)
2. [Assume resources are cleaned up after an `onError` or `onCompleted` messages](#32-assume-resources-are-cleaned-up-after-an-onerror-or-oncompleted-message)
3. [Assume a best effort to stop all outstanding work on Unsubscribe](#33-assume-a-best-effort-to-stop-all-outstanding-work-on-unsubscribe)
4. [Using RxJS](#4-using-rx)
1. [Consider drawing a Marble-diagram](#41-consider-drawing-a-marble-diagram)
2. [Consider passing multiple arguments to `subscribe`](#42-consider-passing-multiple-arguments-to-subscribe)
3. [Consider passing a specific scheduler to concurrency introducing operators](#43-consider-passing-a-specific-scheduler-to-concurrency-introducing-operators)
4. [Call the `observeOn` operator as late and in as few places as possible](#44-call-the-observeon-operator-as-late-and-in-as-few-places-as-possible)
5. [Consider limiting buffers](#45-consider-limiting-buffers)
6. [Make side-effects explicit using the `do`/`tap` operator](#46-make-side-effects-explicit-using-the-dotap-operator)
7. [Assume messages can come through until unsubscribe has completed](#47-assume-messages-can-come-through-until-unsubscribe-has-completed)
8. [Use the `publish` operator to share side-effects](#48-use-the-publish-operator-to-share-side-effects)
5. [Operator implementations](#5-operator-implementations)
1. [Implement new operators by composing existing operators](#51-implement-new-operators-by-composing-existing-operators)
2. [Implement custom operators using `Observable.create`](#52-implement-custom-operators-using-observablecreate)
3. [Protect calls to user code from within an operator](#53-protect-calls-to-user-code-from-within-an-operator)
4. [`subscribe` implementations should not throw](#54-subscribe-implementations-should-not-throw)
5. [`onError` messages should have abort semantics](#55-onerror-messages-should-have-abort-semantics)
6. [Parameterize concurrency by providing a scheduler argument](#56-parameterize-concurrency-by-providing-a-scheduler-argument)
7. [Provide a default scheduler](#57-provide-a-default-scheduler)
8. [The scheduler should be the last argument to the operator](#58-the-scheduler-should-be-the-last-argument-to-the-operator)
9. [Avoid introducing concurrency](#59-avoid-introducing-concurrency)
10. [Hand out all disposables instances created inside the operator to consumers](#510-hand-out-all-disposables-instances-created-inside-the-operator-to-consumers)
11. [Operators should not block](#511-operators-should-not-block)
12. [Avoid deep stacks caused by recursion in operators](#512-avoid-deep-stacks-caused-by-recursion-in-operators)
13. [Argument validation should occur outside `Observable.create`](#513-argument-validation-should-occur-outside-observablecreate)
14. [Unsubscription should be idempotent](#514-unsubscription-should-be-idempotent)
15. [Unsubscription should not throw](#515-unsubscription-should-not-throw)
16. [Custom Observable implementations should follow the RxJS contract](#516-custom-observable-implementations-should-follow-the-rxjs-contract)
17. [Operator implementations should follow guidelines for RxJS usage](#517-operator-implementations-should-follow-guidelines-for-rxjs-usage)
## 1. Introduction ##
This document describes guidelines that aid in developing applications and libraries that use the Reactive Extensions for RxJS library.
The guidelines listed in this document have evolved over time by the Rx team during the development of the RxJS library.
As RxJS continues to evolve, these guidelines will continue to evolve with it. Make sure you have the latest version of this document.
All information described in this document is merely a set of guidelines to aid development. These guidelines do not constitute an absolute truth. They are patterns that the team found helpful; not rules that should be followed blindly. There are situations where certain guidelines do not apply. The team has tried to list known situations where this is the case. It is up to each individual developer to decide if a certain guideline makes sense in each specific situation.
The guidelines in this document are listed in no particular order. There is neither total nor partial ordering in these guidelines.
Please contact us through the [RxJS Issues](https://github.com/Reactive-Extensions/RxJS) for feedback on the guidelines, as well as questions on whether certain guidelines are applicable in specific situations.
## 2. When to Use RxJS ##
### 2.1 Use RxJS for orchestrating asynchronous and event-based computations ###
Code that deals with more than one event or asynchronous computation gets complicated quickly as it needs to build a state-machine to deal with ordering issues. Next to this, the code needs to deal with successful and failure termination of each separate computation. This leads to code that doesn’t follow normal control-flow, is hard to understand and hard to maintain.
RxJS makes these computations first-class citizens. This provides a model that allows for readable and composable APIs to deal with these asynchronous computations.
#### Sample ####
```js
var input = document.getElementById('input');
var dictionarySuggest = Rx.Observable.fromEvent(input, 'keyup')
.map(function () { return input.value; })
.filter(function (text) { return !!text; })
.distinctUntilChanged()
.debounce(250)
.flatMapLatest(searchWikipedia)
.subscribe(
function (results) {
list = [];
list.concat(results.map(createItem));
},
function (err) {
logError(err);
}
);
```
This sample models a common UI paradigm of receiving completion suggestions while the user is typing input.
RxJS creates an observable sequence that models an existing `keyup` event on the input.
It then places several filters and projections on top of the event to make the event only fire if a unique value has come through. (The `keyup` event fires for every key stroke, so also if the user presses left or right arrow, moving the cursor but not changing the input text).
Next it makes sure the event only gets fired after 250 milliseconds of activity by using the `debounce` operator. (If the user is still typing characters, this saves a potentially expensive lookup that will be ignored immediately).
In traditionally written programs, this debouncing would introduce separate callbacks through a timer. This timer could potentially throw exceptions (certain timers have a maximum amount of operations in flight).
Once the user input has been filtered down it is time to perform the dictionary lookup. As this is usually an expensive operation (e.g. a request to a server on the other side of the world), this operation is itself asynchronous as well.
The `flatMap` or `selectMany` operator allows for easy combining of multiple asynchronous operations. It doesn’t only combine success values; it also tracks any exceptions that happen in each individual operation.
In traditionally written programs, this would introduce separate callbacks and a place for exceptions occurring.
If the user types a new character while the dictionary operation is still in progress, we do not want to see the results of that operation anymore. The user has typed more characters leading to a more specific word, seeing old results would be confusing.
The `flatMapLatest` operation makes sure that the dictionary operation is ignored once a new `keyup` has been detected.
Finally we subscribe to the resulting observable sequence. Only at this time our execution plan will be used. We pass two functions to the `subscribe` call:
1. Receives the result from our computation.
2. Receives exceptions in case of a failure occurring anywhere along the computation.
#### When to ignore this guideline ####
If the application/library in question has very few asynchronous/event-based operations or has very few places where these operations need to be composed, the cost of depending on RxJS (redistributing the library as well as the learning curve) might outweigh the cost of manually coding these operations.
### 2.2 Use RxJS to deal with asynchronous sequences of data ###
Several other libraries exist to aid asynchronous operations in the JavaScript ecosystem. Even though these libraries are powerful, they usually work best on operations that return a single message. They usually do not support operations that produce multiple messages over the lifetime of the operation.
RxJS follows the following grammar: `onNext`* (`onCompleted`|`onError`)?. This allows for multiple messages to come in over time. This makes RxJS suitable for both operations that produce a single message, as well as operations that produce multiple messages.
```js
var fs = require('fs');
var Rx = require('rx');
// Read/write from stream implementation
function readAsync(fd, chunkSize) { /* impl */ }
function appendAsync(fd, buffer) { /* impl */ }
function encrypt(buffer) { /* impl */}
//open a 4GB file for asynchronous reading in blocks of 64K
var inFile = fs.openSync('4GBfile.txt', 'r+');
var outFile = fs.openSync('Encrypted.txt', 'w+');
readAsync(inFile, 2 << 15)
.map(encrypt)
.flatMap(function (data) {
return appendAsync(outFile, data);
})
.subscribe(
function () { },
function (err) {
console.log('An error occurred while encrypting the file: %s', err.message);
fs.closeSync(inFile);
fs.closeSync(outFile);
},
function () {
console.log('Successfully encrypted the file.');
fs.closeSync(inFile);
fs.closeSync(outFile);
}
);
```
In this sample, a 4 GB file is read in its entirety, encrypted and saved out to another file.
Reading the whole file into memory, encrypting it and writing out the whole file would be an expensive operation.
Instead, we rely on the fact that RxJS can produce many messages.
We read the file asynchronously in blocks of 64K. This produces an observable sequence of byte arrays. We then encrypt each block separately (for this sample we assume the encryption operation can work on separate parts of the file). Once the block is encrypted, it is immediately sent further down the pipeline to be saved to the other file. The `appendAsync` operation is an asynchronous operation that can process multiple messages.
#### When to ignore this guideline ####
If the application/library in question has very few operations with multiple messages, the cost of depending on RxJS (redistributing the library as well as the learning curve) might outweigh the cost of manually coding these operations.
## 3. The RxJS Contract ##
### 3.1 The RxJS Grammar ###
Messages sent to instances of the `Observer` object follow the following grammar:
onNext* (onCompleted | onError)?
This grammar allows observable sequences to send any amount (0 or more) of `onNext` messages to the subscribed observer instance, optionally followed by a single success (`onCompleted`) or failure (`onError`) message.
The single message indicating that an observable sequence has finished ensures that consumers of the observable sequence can deterministically establish that it is safe to perform cleanup operations.
A single failure further ensures that abort semantics can be maintained for operators that work on multiple observable sequences.
#### Sample ####
```js
var count = 0;
xs.subscribe(
function () {
count++;
},
function (err) {
console.log('Error: %s', err.message);
},
function () {
console.log('OnNext has been called %d times', count);
}
);
```
In this sample we safely assume that the total amount of calls to the OnNext method won’t change once the OnCompleted method is called as the observable sequence follows the Rx grammar.
#### When to ignore this guideline ####
Ignore this guideline only when working with a non-conforming implementation of the Observable object.
### 3.2 Assume resources are cleaned up after an `onError` or `onCompleted` message ###
Paragraph 3.1 states that no more messages should arrive after an `onError` or `onCompleted` message. This makes it possible to cleanup any resource used by the subscription the moment an `onError` or `onCompleted` arrives. Cleaning up resources immediately will make sure that any side-effect occurs in a predictable fashion. It also makes sure that the runtime can reclaim these resources.
#### Sample ####
```js
var fs = require('fs');
var Rx = require('rx');
function appendAsync(fd, buffer) { /* impl */ }
function openFile(path, flags) {
var fd = fs.openSync(path, flags);
return Rx.Disposable.create(function () {
fs.closeSync(fd);
});
}
Rx.Observable.
using(
function () { return openFile('temp.txt', 'w+'); },
function (fd) {
return Rx.Observable.range(0, 10000)
.map(function (v) { return Buffer(v); })
.flatMap(function (buffer) {
return appendAsync(fd, buffer);
});
}
)
.subscribe();
```
In this sample the Using operator creates a resource that will be disposed upon unsubscription. The Rx contract for cleanup ensures that unsubscription will be called automatically once an `onError` or `onCompleted` message is sent.
#### When to ignore this guideline ####
There are currently no known cases where to ignore this guideline.
### 3.3 Assume a best effort to stop all outstanding work on Unsubscribe ###
When unsubscribe is called on an observable subscription, the observable sequence will make a best effort attempt to stop all outstanding work. This means that any queued work that has not been started will not start.
Any work that is already in progress might still complete as it is not always safe to abort work that is in progress. Results from this work will not be signaled to any previously subscribed observer instances.
#### Sample 1
```js
Observable.timer(2000).subscribe(...).dispose()
```
In this sample subscribing to the observable sequence generated by Timer will queue an action on the `Scheduler.timeout` scheduler to send out an `onNext` message in 2 seconds. The subscription then gets canceled immediately. As the scheduled action has not started yet, it will be removed from the scheduler.
#### Sample 2
```js
Rx.Observable.startAsync(function () {
return Q.delay(2000);
})
.subscribe(...).dispose();
```
In this sample the `startAsync` operator will immediately schedule the execution of the lambda provided as its argument. The subscription registers the observer instance as a listener to this execution. As the lambda is already running once the subscription is disposed, it will keep running and its return value is ignored.
## 4. Using Rx ##
### 4.1 Consider drawing a Marble-diagram ###
Draw a marble-diagram of the observable sequence you want to create. By drawing the diagram, you will get a clearer picture on what operator(s) to use.
A marble-diagram is a diagram that shows event occurring over time. A marble diagram contains both input and output sequences(s).
By drawing the diagram we can see that we will need some kind of delay after the user input, before firing of another asynchronous call. The delay in this sample maps to the `debounce` operator. To create another observable sequence from an observable sequence we will use the `flatMap` or `selectMany` operator. This
will lead to the following code:
```js
var dictionarySuggest = userInput
.debounce(250)
.flatMap(function (input) { return serverCall(input); });
```
#### When to ignore this guideline ####
This guideline can be ignored if you feel comfortable enough with the observable sequence you want to write. However, even the Rx team members will still grab the whiteboard to draw a marble-diagram once in a while.
### 4.2 Consider passing multiple arguments to `subscribe` ###
For convenience, Rx provides an overload to the `subscribe` method that takes functions instead of an Observer argument.
The Observer object would require implementing all three methods (`onNext`, `onError` & `onCompleted`). The extensions to the `subscribe` method allow developers to use defaults chosen for each of these methods.
E.g. when calling the `subscribe` method that only has an `onNext` argument, the `onError` behavior will be to rethrow the exception on the thread that the message comes out from the observable sequence. The `onCompleted` behavior in this case is to do nothing.
In many situations, it is important to deal with the exception (either recover or abort the application gracefully).
Often it is also important to know that the observable sequence has completed successfully. For example, the application notifies the user that the operation has completed.
Because of this, it is best to provide all 3 arguments to the subscribe function.
RxJS also provides three convenience methods which only subscribe to the part of the sequence that is desired. The other handlers will default to their original behaviors. There are three of such functions:
- `subscribeOnNext`: for `onNext` messages only
- `subscribeOnError`: for `onError` messages only
- `subscribeOnCompleted`: for `onCompleted` messages only.
#### When to ignore this guideline ####
- When the observable sequence is guaranteed not to complete, e.g. an event such as keyup.
- When the observable sequence is guaranteed not to have `onError` messages (e.g. an event, a materialized observable sequence etc…).
- When the default behavior is the desirable behavior.
### 4.3 Consider passing a specific scheduler to concurrency introducing operators ###
Rather than using the `observeOn` operator to change the execution context on which the observable sequence produces messages, it is better to create concurrency in the right place to begin with. As operators parameterize introduction of concurrency by providing a scheduler argument overload, passing the right scheduler will lead to fewer places where the ObserveOn operator has to be used.
#### Sample ####
```js
Rx.Observable.range(0, 90000, Rx.Scheduler.requestAnimationFrame)
.subscribe(draw);
```
In this sample, callbacks from the `range` operator will arrive by calling `window.requestAnimationFrame`. The default overload of `range` would place the `onNext` call on the `Rx.Scheduler.currentThread` which is used when recursive scheduling is required immediately. By providing the `Rx.Scheduler.requestAnimationFrame` scheduler, all messages from this observable sequence will originiate on the `window.requestAnimationFrame` callback.
#### When to ignore this guideline ####
When combining several events that originate on different execution contexts, use guideline 4.4 to put all messages on a specific execution context as late as possible.
### 4.4 Call the `observeOn` operator as late and in as few places as possible ###
By using the `observeOn` operator, an action is scheduled for each message that comes through the original observable sequence. This potentially changes timing information as well as puts additional stress on the system. Placing this operator later in the query will reduce both concerns.
#### Sample ####
```js
var result = xs.debounce(1000)
.flatMap(function (x) {
return ys.takeUntil(zs).sample(250).map(function (y) { return x + y });
})
.merge(ws)
.filter(function (x) { return x < 10; })
.observeOn(Rx.Scheduler.requestAnimationFrame);
```
This sample combines many observable sequences running on many different execution contexts. The query filters out a lot of messages. Placing the `observeOn` operator earlier in the query would do extra work on messages that would be filtered out anyway. Calling the `observeOn` operator at the end of the query will create the least performance impact.
#### When to ignore this guideline ####
Ignore this guideline if your use of the observable sequence is not bound to a specific execution context. In that case do not use the `observeOn` operator.
### 4.5 Consider limiting buffers ###
RxJS comes with several operators and classes that create buffers over observable sequences, e.g. the `replay` operator. As these buffers work on any observable sequence, the size of these buffers will depend on the observable sequence it is operating on. If the buffer is unbounded, this can lead to memory pressure. Many buffering operators provide policies to limit the buffer, either in time or size. Providing this limit will address memory pressure issues.
#### Sample ####
```js
var result = xs.replay(null, 10000, 1000 * 60 /* 1 hr */).refCount();
```
In this sample, the `replay` operator creates a buffer. We have limited that buffer to contain at most 10,000 messages and keep these messages around for a maximum of 1 hour.
#### When to ignore this guideline ####
When the amount of messages created by the observable sequence that populates the buffer is small or when the buffer size is limited.
### 4.6 Make side-effects explicit using the `do`/`tap` operator ###
As many Rx operators take functions as arguments, it is possible to pass any valid user code in these arguments. This code can change global state (e.g. change global variables, write to disk etc...).
The composition in Rx runs through each operator for each subscription (with the exception of the sharing operators, such as `publish`). This will make every side-effect occur for each subscription.
If this behavior is the desired behavior, it is best to make this explicit by putting the side-effecting code
in a `do`/`tap` operator. There are overloads to this method which call the specified method only, for example `doOnNext`/`tapOnNext`, `doOnError`/`tapOnError`,`doOnCompleted`/`tapOnCompleted`
#### Sample ####
```js
var result = xs
.filter(function (x) { return x.failed; })
.tap(function (x) { log(x); });
```
In this sample, messages are filtered for failure. The messages are logged before handing them out to the code subscribed to this observable sequence. The logging is a side-effect (e.g. placing the messages in the computer’s event log) and is explicitly done via a call to the `do`/`tap` operator.
### 4.7 Assume messages can come through until unsubscribe has completed ###
As RxJS uses a push model, messages can be sent from different execution contexts. Messages can be in flight while calling unsubscribe. These messages can still come through while the call to unsubscribe is in progress. After control has returned, no more messages will arrive. The unsubscription process can still be in progress on a different context.
#### When to ignore this guideline ####
Once the `onCompleted` or `onError` method has been received, the RxJS grammar guarantees that the subscription can be considered to be finished.
### 4.8 Use the `publish` operator to share side-effects ###
As many observable sequences are cold [\(see cold vs. hot on Channel 9\)](http://channel9.msdn.com/Blogs/J.Van.Gogh/Rx-API-in-depth-Hot-and-Cold-observables), each subscription will have a
separate set of side-effects. Certain situations require that these side-effects occur only once. The `publish` operator provides a mechanism to share subscriptions by broadcasting a single subscription to multiple subscribers.
There are several overloads of the `publish` operator. The most convenient overloads are the ones that provide a function with a wrapped observable sequence argument that shares the side-effects.
#### Sample ####
```js
var xs = Rx.Observable.create(function (observer) {
console.log('Side effect');
observer.onNext('hi!');
observer.onCompleted();
});
xs.publish(function (sharedXs) {
sharedXs.subscribe(console.log.bind(console));
sharedXs.subscribe(console.log.bind(console));
return sharedXs;
}).subscribe();
```
In this sample, xs is an observable sequence that has side-effects (writing to the console). Normally each separate subscription will trigger these side-effects. The `publish` operator uses a single subscription to xs for all subscribers to sharedXs.
#### When to ignore this guideline ####
Only use the `publish` operator to share side-effects when sharing is required. In most situations you can create separate subscriptions without any problems: either the subscriptions do not have side-effects or the side effects can execute multiple times without any issues.
## 5. Operator implementations ##
### 5.1 Implement new operators by composing existing operators ###
Many operations can be composed from existing operators. This will lead to smaller, easier to maintain code. The Rx team has put a lot of effort in dealing with all corner cases in the base operators. By reusing these operators you’ll get all that work for free in your operator.
#### Sample ####
```js
Rx.Observable.prototype.flatMap = function (selector) {
return this.map(selector).mergeAll();
};
```
In this sample, the `flatMap` or `selectMany` operator uses two existing operators: `map` and `mergeAll`. The `map` operator already deals with any issues around the selector function throwing an exception. The `mergeAll` operator already deals with concurrency issues of multiple observable sequences firing at the same time.
#### When to ignore this guideline ####
- No appropriate set of base operators is available to implement this operator.
- Performance analysis proves that the implementation using existing operators has performance issues. Such can be caused by `materialize`.
### 5.2 Implement custom operators using `Observable.create` ###
When it is not possible to follow guideline 5.1, use the Observable.Create(WithDisposable) method to create an observable sequence as it provides several protections make the observable sequence follow the RxJS contract.
- When the observable sequence has finished (either by firing `onError` or `onCompleted`), any subscription will automatically be unsubscribed.
- Any subscribed observer instance will only see a single OnError or OnCompleted message. No more messages are sent through. This ensures the Rx grammar of onNext* (onError|onCompleted)?
#### Sample ####
```js
Rx.Observable.prototype.map = function (selector, thisArg) {
var source = this;
return Rx.Observable.create(function (observer) {
var idx = 0;
return source.subscribe(
function (x) {
var result;
try {
result = selector.call(thisArg, x, idx++, source);
} catch (e) {
observer.onError(e);
return;
}
observer.onNext(result);
},
observer.onError.bind(observer),
observer.onCompleted.bind(observer)
);
})
};
```
In this sample, `map` uses the `Observable.create` operator to return a new instance of the Observable class. This ensures that no matter the implementation of the source observable sequence, the output observable sequence follows the Rx contract . It also ensures that the lifetime of subscriptions is a short as possible.
#### When to ignore this guideline ####
- The operator needs to return an observable sequence that doesn’t follow the Rx contract. This should usually be avoided (except when writing tests to see how code behaves when the contract is broken)
- The object returned needs to implement more than the Observable class (e.g. Subject, or a custom class).
### 5.3 Protect calls to user code from within an operator ###
When user code is called from within an operator, this is potentially happening outside of the execution context of the call to the operator (asynchronously). Any exception that happens here will cause the program to terminate unexpectedly. Instead it should be fed through to the subscribed observer instance so that the exception can be dealt with by the subscribers.
Common kinds of user code that should be protected:
- Selector functions passed in to the operator.
- Comparer functions passed into the operator.
**Note:** calls to `Scheduler` implementations are not considered for this guideline. The reason for this is that only a small set of issues would be caught as most schedulers deal with asynchronous calls. Instead, protect the arguments passed to schedulers inside each scheduler implementation.
#### Sample ####
```js
Rx.Observable.prototype.map = function (selector, thisArg) {
var source = this;
return Rx.Observable.create(function (observer) {
var idx = 0;
return source.subscribe(
function (x) {
var result;
try {
result = selector.call(thisArg, x, idx++, source);
} catch (e) {
observer.onError(e);
return;
}
observer.onNext(result);
},
observer.onError.bind(observer),
observer.onCompleted.bind(observer)
);
})
};
```
This sample invokes a selector function which is user code. It catches any exception resulting from this call and transfers the exception to the subscribed observer instance through the `onError` call.
#### When to ignore this guideline ####
Ignore this guideline for calls to user code that are made before creating the observable sequence (outside of the `Observable.create` call). These calls are on the current execution context and are allowed to follow normal control flow.
**Note:** do not protect calls to `subscribe`, `dispose`, `onNext`, `onError` and `onCompleted` methods. These calls are on the edge of the monad. Calling the `onError` method from these places will lead to unexpected behavior.
### 5.4 `subscribe` implementations should not throw ###
As multiple observable sequences are composed, subscribe to a specific observable sequence might not happen at the time the user calls `subscribe` (e.g. Within the `concat` operator, the second observable sequence argument to `concat` will only be subscribed to once the first observable sequence has completed). Throwing an exception would bring down the program. Instead exceptions in subscribe should be tunneled to the `onError` method.
#### Sample ####
```js
var CLOSED = 3;
function readWebSocket(socket) {
return Rx.Observable.create(function (observer) {
if (socket.readyState === CLOSED) {
observer.onError(new Error('The websocket is no longer open.'));
return;
}
// Rest of the implementation goes here
});
}
```
In this sample, an error condition is detected in the subscribe method implementation. An error is raised by calling the `onError` method instead of throwing the exception. This allows for proper handling of the exception if `subscribe` is called outside of the execution context of the original call to Subscribe by the user.
#### When to ignore this guideline ####
When a catastrophic error occurs that should bring down the whole program anyway.
### 5.5 `onError` messages should have abort semantics
As normal control flow in JavaScript uses abort semantics for exceptions (the stack is unwound, current code path is interrupted), RxJS mimics this behavior. To ensure this behavior, no messages should be sent out by an operator once one of it sources has an error message or an exception is thrown within the operator.
#### Sample ####
```js
Rx.Observable.prototype.minimumBuffer = function (bufferSize) {
var source = this;
return Rx.Observable.create(function (observer) {
var data = [];
return source.subscribe(
function (value) {
data = data.concat(value);
if (data.length > bufferSize) {
observer.onNext(data.slice(0));
data = [];
}
},
observer.onError.bind(observer),
function () {
if (data.length > 0) {
observer.onNext(data.slice(0));
}
observer.onCompleted();
}
);
});
};
```
In this sample, a buffering operator will abandon the observable sequence as soon as the subscription to source encounters an error. The current buffer is not sent to any subscribers, maintain abort semantics.
#### When to ignore this guideline ####
There are currently no known cases where to ignore this guideline.
### 5.6 Parameterize concurrency by providing a scheduler argument ###
As there are many different notions of concurrency, and no scenario fits all, it is best to parameterize the concurrency an operator introduces. The notion of parameterizing concurrency in RxJS is abstracted through the `Scheduler` class.
#### Sample ####
```js
Rx.Observable.just = function (value, scheduler) {
return Rx.Observable.create(function (observer) {
return scheduler.schedule(function () {
observer.onNext(value);
observer.onCompleted();
});
});
};
```
In this sample, the `just` operator parameterizes the level of concurrency the operator has by providing a scheduler argument. It then uses this scheduler to schedule the firing of the `onNext` and `onCompleted` messages.
#### When to ignore this guideline ####
- The operator is not in control of creating the concurrency (e.g. in an operator that converts an event into an observable sequence, the source event is in control of firing the messages, not the operator).
- The operator is in control, but needs to use a specific scheduler for introducing concurrency.
### 5.7 Provide a default scheduler ###
In most cases there is a good default that can be chosen for an operator that has parameterized concurrency through guideline 5.6. This will make the code that uses this operator more succinct.
**Note:** Follow guideline 5.9 when choosing the default scheduler, using the immediate scheduler where possible, only choosing a scheduler with more concurrency when needed.
#### Sample ####
```js
Rx.Observable.just = function (value, scheduler) {
// Pick a default scheduler, in this case, immediately
Rx.helpers.isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
return Rx.Observable.create(function (observer) {
return scheduler.schedule(function () {
observer.onNext(value);
observer.onCompleted();
});
});
};
```
In this sample, we provided a default scheduler if not provided by the caller.
#### When to ignore this guideline ####
Ignore this guideline when no good default can be chosen.
### 5.8 The scheduler should be the last argument to the operator ###
Adding the scheduler as the last argument is a must for all operators introducing concurrency. This is to ensure that the schedulers are optional, and a default one can be chosen. This also makes the programming experience much more predictable.
#### Sample ####
```js
Rx.Observable.just = function (value, scheduler) {
// Pick a default scheduler, in this case, immediately
Rx.helpers.isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
return Rx.Observable.create(function (observer) {
return scheduler.schedule(function () {
observer.onNext(value);
observer.onCompleted();
});
});
};
```
In this sample the `return` operator has two parameters, and the scheduler parameter defaults to the immediate scheduler if not provided. As the scheduler argument is the last argument, adding or omitting the argument is clearly visible.
#### When to ignore this guideline ####
JavaScript supports rest arguments syntax. With this syntax, the rest arguments has to be the last argument. Make the scheduler the final to last argument in this case.
### 5.9 Avoid introducing concurrency ###
By adding concurrency, we change the timeliness of an observable sequence. Messages will be scheduled to arrive later. The time it takes to deliver a message is data itself, by adding concurrency we skew that data. This includes not using such mechanisms as `setTimeout`, `setImmediate`, `requestAnimationFrame`, `process.nextTick`, etc which should be avoided directly in your code, and instead be wrapped by a `Scheduler` class.
#### Sample 1 ####
```js
Rx.Observable.prototype.map = function (selector, thisArg) {
var source = this;
return Rx.Observable.create(function (observer) {
var idx = 0;
return source.subscribe(
function (x) {
var result;
try {
result = selector.call(thisArg, x, idx++, source);
} catch (e) {
observer.onError(e);
return;
}
observer.onNext(result);
},
observer.onError.bind(observer),
observer.onCompleted.bind(observer)
);
})
};
```
In this sample, the select operator does not use a scheduler to send out the `onNext` message. Instead it uses the source observable sequence call to `onNext` to process the message, hence staying in the same time-window.
#### Sample 2 ####
```js
Rx.Observable.just = function (value, scheduler) {
// Pick a default scheduler, in this case, immediately
Rx.helpers.isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
return Rx.Observable.create(function (observer) {
return scheduler.schedule(function () {
observer.onNext(value);
observer.onCompleted();
});
});
};
```
In this case, the default scheduler for the `just` operator is the immediate scheduler. This scheduler does not introduce concurrency.
#### When to ignore this guideline ####
Ignore this guideline in situations where introduction of concurrency is an essential part of what the operator does.
**NOTE:** When we use the Immediate scheduler or call the observer directly from within the call to `subscribe`, we make the `subscribe` call blocking. Any expensive computation in this situation would indicate a candidate for introducing concurrency.
### 5.10 Hand out all disposables instances created inside the operator to consumers ###
`Disposable` instances control lifetime of subscriptions as well as cancelation of scheduled actions. RxJS gives users an opportunity to unsubscribe from a subscription to the observable sequence using disposable instances.
After a subscription has ended, no more messages are allowed through. At this point, leaving any state alive inside the observable sequence is inefficient and can lead to unexpected semantics.
To aid composition of multiple disposable instances, RxJS provides a set of classes implementing `Disposable` such as:
Name | Description
-------------------------- | ---------------------------------------------------------------
CompositeDisposable | Composes and disposes a group of disposable instances together.
SerialDisposable | A place holder for changing instances of disposable instances. Once new disposable instance is placed, the old disposable instance is disposed.
SingleAssignmentDisposable | A place holder for a single instance of a disposable.
ScheduledDisposable | Uses a scheduler to dispose an underlying disposable instance.
#### Sample ####
```js
Observable.prototype.zip = function () {
var parent = this,
sources = slice.call(arguments),
resultSelector = sources.pop();
sources.unshift(parent);
return new AnonymousObservable(function (observer) {
var n = sources.length,
queues = arrayInitialize(n, function () { return []; }),
isDone = arrayInitialize(n, function () { return false; });
function next(i) {
var res, queuedValues;
if (queues.every(function (x) { return x.length > 0; })) {
try {
queuedValues = queues.map(function (x) { return x.shift(); });
res = resultSelector.apply(parent, queuedValues);
} catch (ex) {
observer.onError(ex);
return;
}
observer.onNext(res);
} else if (isDone.filter(function (x, j) { return j !== i; }).every(identity)) {
observer.onCompleted();
}
};
function done(i) {
isDone[i] = true;
if (isDone.every(function (x) { return x; })) {
observer.onCompleted();
}
}
var subscriptions = new Array(n);
for (var idx = 0; idx < n; idx++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
Rx.helpers.isPromise(source) && (source = Rx.Observable.fromPromise(source));
sad.setDisposable(source.subscribe(function (x) {
queues[i].push(x);
next(i);
}, observer.onError.bind(observer), function () {
done(i);
}));
subscriptions[i] = sad;
})(idx);
}
return new CompositeDisposable(subscriptions);
});
};
```
In this sample, the operator groups all disposable instances controlling the various subscriptions together and returns the group as the result of subscribing to the outer observable sequence. When a user of this operator subscribes to the resulting observable sequence, he/she will get back a disposable instance that controls subscription to all underlying observable sequences.
#### When to ignore this guideline ####
There are currently no known instances where this guideline should be ignored.
### 5.11 Operators should not block ###
RxJS is a library for composing asynchronous and event-based programs using observable collections.
By making an operator blocking we lose these asynchronous characteristics. We also potentially lose composability (e.g. by returning a value typed as `T` instead of `Observable`). This is in contrast to the Array#extras such as `sum`, `reduce`, `some` and `every` which return a single value.
#### Sample ####
```js
Rx.Observable.prototype.sum = function () {
return this.reduce(function (acc, x) { return acc + x; }, 0);
};
```
In this sample, the `sum` operator has a return type of `Observable` instead of `Number`. By doing this, the operator does not block. It also allows the result value to be used in further composition.
#### When to ignore this guideline ####
There are currently no known instances where this guideline should be ignored.
### 5.12 Avoid deep stacks caused by recursion in operators ###
As code inside Rx operators can be called from different execution context in many different scenarios, it is nearly impossible to establish how deep the stack is before the code is called. If the operator itself has a deep stack (e.g. because of recursion), the operator could trigger a stack overflow quicker than one might expect.
There are two recommended ways to avoid this issue:
- Use the recursive `scheduleRecursive` methods on the `Scheduler`
- Implement an infinite looping generator using the yield iterator pattern, convert it to an observable sequence using the `from` operator.
#### Sample 1 ####
```js
Rx.Observable.repeat = function (value, scheduler) {
return Rx.Observable.create(function (observer) {
return scheduler.scheduleRecursive(function (self) {
observer.onNext(value);
self();
});
});
};
```
In this sample, the recursive `scheduleRecursive` method is used to allow the scheduler to schedule the next iteration of the recursive function. Schedulers such as the current thread scheduler do not rely on stack semantics. Using such a scheduler with this pattern will avoid stack overflow issues.
#### Sample 2 ####
```js
Rx.Observable.repeat = function (value) {
return Rx.Observable.from(
function* () {
while(true) { yield value; }
}());
};
```
The yield iterator pattern ensures that the stack depth does not increase drastically. By returning an infinite generator with the `from` operator can build an infinite observable sequence.
#### When to ignore this guideline ####
There are currently no known instances where this guideline should be ignored.
### 5.13 Argument validation should occur outside `Observable.create`
As guideline 5.3 specifies that the `Observable.create` operator should not throw, any argument validation that potentially throws exceptions should be done outside the `Observable.create` operator.
#### Sample ####
```js
Rx.Observable.prototype.map = function (selector, thisArg) {
if (this == null) {
throw new TypeError('Must be an instance of an Observable');
}
if (selector == null) {
throw new TypeError('selector cannot be null/undefined');
}
var selectorFn = typeof selector !== 'function' ?
function () { return selector; } :
selector;
var source = this;
return Rx.Observable.create(function (observer) {
var idx = 0;
return source.subscribe(
function (x) {
var result;
try {
result = selectorFn.call(thisArg, x, idx++, source);
} catch (e) {
observer.onError(e);
return;
}
observer.onNext(result);
},
observer.onError.bind(observer),
observer.onCompleted.bind(observer)
);
});
};
```
In this sample, the arguments are checked for null values before the `Observable.create` operator is called.
#### When to ignore this guideline ####
Ignore this guideline if some aspect of the argument cannot be checked until the subscription is active.
### 5.14 Unsubscription should be idempotent ###
The observable `subscribe` method returns a `Disposable` instance that can be used to clean up the subscription. The `Disposable` instance doesn’t give any information about what the state of the subscription is. As consumers do not know the state of the subscription, calling the `dispose` method multiple times should be allowed. Only the first call the side-effect of cleaning up the subscription should occur.
#### Sample ####
```js
var subscription = xs.subscribe(function (x) { console.log(x); });
subscription.dispose();
subscription.dispose();
```
In this sample, the subscription is disposed twice, the first time the subscription will be cleaned up and the second call will be a no-op.
### 5.15 Unsubscription should not throw ###
As the RxJS’s composition makes that subscriptions are chained, so are unsubscriptions. Because of this, any operator can call an unsubscription at any time. Because of this, just throwing an exception will lead to the application crashing unexpectedly. As the observer instance is already unsubscribed, it cannot be used for receiving the exception either. Because of this, exceptions in unsubscriptions should be avoided.
#### When to ignore this guideline ####
There are currently no known cases where to ignore this guideline.
### 5.16 Custom `Observable` implementations should follow the RxJS contract ###
When it is not possible to follow guideline 5.1, the custom implementation of the `Observable` class should still follow the RxJS contract in order to get the right behavior from the RxJS operators.
#### When to ignore this guideline ####
Only ignore this guideline when writing observable sequences that need to break the contract on purpose (e.g. for testing).
### 5.17 Operator implementations should follow guidelines for RxJS usage ###
As Rx is a composable API, operator implementations often use other operators for their implementation (see paragraph 5.1). RxJS usage guidelines should be strongly considered when implementing these operators.
#### When to ignore this guideline ####
As described in the introduction, only follow a guideline if it makes sense in that specific situation.
================================================
FILE: doc/gettingstarted/backpressure.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Backpressure #
When it comes to streaming data, streams can be overly chatty in which the consumer cannot keep up with the producer. To that end, we need mechanisms to control the source so that the consumer does not get overwhelmed. These mechanisms can come in either the form of lossy or loss-less operations, each of which depends on the requirements. For example, if you miss a few mouse movements, it may not be a problem, however, if you miss a few bank transactions, that could be a definite problem. This section covers which techniques you can use to handle backpressure in either lossy or loss-less ways.
For example, imagine using the [`zip`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/zip.md) operator to zip together two infinite Observables, one of which emits items twice as frequently as the other. A naive implementation of the zip operator would have to maintain an ever-expanding buffer of items emitted by the faster Observable to eventually combine with items emitted by the slower one. This could cause RxJS to seize an unwieldy amount of system resources.
## Hot and Cold Observables and Multicast ##
A cold Observable emits a particular sequence of items, but can begin emitting this sequence when its Observer finds it to be convenient, and at whatever rate the Observer desires, without disrupting the integrity of the sequence. For example if you convert a iterable such as array, Map, Set, or generator into an Observable, that Observable will emit the same sequence of items no matter when it is later subscribed to or how frequently those items are observed. Examples of items emitted by a cold Observable might include the results of a database query, file retrieval, or web request.
A hot Observable begins generating items to emit immediately when it is created. Subscribers typically begin observing the sequence of items emitted by a hot Observable from somewhere in the middle of the sequence, beginning with the first item emitted by the Observable subsequent to the establishment of the subscription. Such an Observable emits items at its own pace, and it is up to its observers to keep up. Examples of items emitted by a hot Observable might include mouse & keyboard events, system events, or stock prices.
When a cold Observable is multi-cast (when it is converted into a `ConnectableObservable` and its [`connect`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/connect.md) method is called), it effectively becomes hot and for the purposes of backpressure and flow-control it should be treated as a hot Observable.
Cold Observables are ideal subjects for the reactive pull model of backpressure described below. Hot observables are typically not designed to cope well with a reactive pull model, and are better candidates for some of the other flow control strategies discussed on this page, such as the use of the `pausableBuffered` or `pausable` operators, throttling, buffers, or windows.
## Lossy Backpressure ##
There are a number of ways that an observable sequence can be controlled so that the consumer does not get overwhelmed through lossy operations, meaning that packets will be dropped in between pause and resume actions.
### Debounce ###
The first technique for lossy backpressure is called [`debounce`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md) which only emits an item from the source Observable after a particular timespan has passed without the Observable emitting any other items. This is useful in scenarios such as if the user is typing too fast and you do not want to yield every keystroke, and instead wait half a second after the person stopped typing before yielding the value.
```js
var debounced = Rx.Observable.fromEvent(input, 'keyup')
.map(function (e) { return e.target.value; })
.debounce(500 /* ms */);
debounced.subscribeOnNext(function (value) {
console.log('Input value: %s', value);
});
```
### Throttling ###
Another technique to deal with an observable sequence which is producing too much for the consumer is through throttling with the use of the [`throttle`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/throttle.md) method which emits the first items emitted by an Observable within periodic time intervals. Throttling can be especially useful for rate limiting execution of handlers on events like resize and scroll.
```js
var throttled = Rx.Observable.fromEvent(window, 'resize')
.throttle(250 /* ms */);
throttled.subscribeOnNext(function (e) {
console.log('Window inner height: %d', window.innerHeight);
console.log('Window inner width: %d', window.innerWidth);
});
```
### Sampling Observables ###
You can also at certain intervals extract values from the observable sequence using the [`sample`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sample.md) method. This is useful if you want values from say a stock ticker every five seconds or so without having to consume the entire observable sequence.
```js
var sampled = getStockData()
.sample(5000 /* ms */);
sampled.subscribeOnNext(function (data) {
console.log('Stock data: %o', data);
});
```
### Pausable Observables ###
The ability to pause and resume is also a powerful concept which is offered in RxJS in both lossy and loss-less versions. In the case of lossy backpressure, the [`pausable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/pausable.md) operator can be used to stop listening and then resume listening at a later time by calling `pause` and `resume` respectively on the observable sequence. For example we can take some observable sequence and call `pausable`, then call `pause` to pause the sequence and `resume` within 5 seconds. Note that any data that comes in between the pause and resume are lost. Note that this only works for hot observables and is unsuitable for cold observables as they will restart upon resume.
```js
var pausable = getSomeObservableSource()
.pausable();
pausable.subscribeOnNext(function (data) {
console.log('Data: %o', data);
});
pausable.pause();
// Resume in five seconds
setTimeout(function () {
pausable.resume();
}, 5000);
```
## Loss-less Backpressure ##
In addition to supporting lossy backpressure mechanisms, RxJS also supports ways of getting the data in such a way that it is able to be fully consumed by the consumer at its own pace. There are a number of strategies at work including using buffers that work with timespans, count or both, pausable buffers, reactive pull, etc.
### Buffers and Windows ###
The first strategy of dealing with an overly chatty producer is through the use of buffers. This allows the consumer to set either the number of items they wish to wait for at a time, or a particular timespan, or both, whichever comes first. This is useful in a number of cases, for example if you want some data within a window for comparison purposes in addition to chunking up data as you need it.
The [`bufferWithCount`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/bufferwithcount.md) method allows us to specify the number of items that you wish to capture in a buffer array before yielding it to the consumer. An impractical yet fun use of this is to calculate whether the user has input the Konami Code for example.
```js
var codes = [
38, // up
38, // up
40, // down
40, // down
37, // left
39, // right
37, // left
39, // right
66, // b
65 // a
];
function isKonamiCode(buffer) {
return codes.toString() === buffer.toString();
}
var keys = Rx.Observable.fromEvent(document, 'keyup')
.map(function (e) { return e.keyCode; })
.bufferWithCount(10, 1)
.filter(isKonamiCode)
.subscribeOnNext(function () {
console.log('KONAMI!');
});
```
On the other hand, you can also get the data within a buffer for a given amount of time with the [`bufferWithTime`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/bufferwithtime.md). This is useful for example if you are tracking volume of data that is coming across the network, which can then be handled uniformly.
```js
var source = getStockData()
.bufferWithTime(5000, 1000) // time in milliseconds
.subscribeOnNext(function (data) {
data.forEach(function (d) {
console.log('Stock: %o', d);
});
});
```
In order to keep buffers from filling too quickly, there is a method to cap the buffer by specifying ceilings for count and timespan, whichever occurs first. For example, the network could be particularly quick with the data for the specified time, and other times not, so to keep the data levels even, you can specify this threshold via the [`bufferWithTimeOrCount`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/bufferwithtimeorcount.md) method
```js
var source = getStockData()
.bufferWithTimeOrCount(5000 /* ms */, 100 /* items */)
.subscribeOnNext(function (data) {
data.forEach(function (d) {
console.log('Stock: %o', d);
});
});
```
### Pausable Buffers ###
The [`pausable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/pausable.md) method is great at dealing with hot observables where you would want to pause and resume while dropping data, however, you may want to preserve that data between the `pause` and `resume` calls. To that end, we have introduced the [`pausableBuffered`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/pausablebuffered.md) method which keeps a running buffer between `pause` is called and is drained when `resume` is called. This then leaves the discretion up to the developer to decide when to pause and resume and in the mean time, no data is lost.
```js
var source = getStockData()
.pausableBuffered();
source.subscribeOnNext(function (stock) {
console.log('Stock data: %o', stock);
});
source.pause();
// Resume after five seconds
setTimeout(function () {
// Drains the buffer and subscribeOnNext is called with the data
source.resume();
}, 5000);
```
### Controlled Observables ###
In more advanced scenarios, you may want to control the absolute number of items that you receive at a given time, and the rest is buffered via the `controlled` method. For example, you can pull 10 items, followed by 20 items, and is up to the discretion of the developer. This is more in-line with the efforts from the [Reactive Streams](http://www.reactive-streams.org/) effort to effectively turn the push stream into a push/pull stream.
```js
var source = getStockData()
.controlled();
source.subscribeOnNext(function (stock) {
console.log('Stock data: %o', stock);
});
source.request(2);
// Keep getting more after 5 seconds
setInterval(function () {
source.request(2);
}, 5000);
```
### Future Work ###
This is of course only the beginning of the work with backpressure as there are many other strategies that can be considered. In future versions of RxJS, the idea of the controlled observable will be baked into the subscription itself which then allows the backpressure to be an essential part of the contract or requesting n number of items.
================================================
FILE: doc/gettingstarted/callbacks.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Bridging to Callbacks #
Besides events, other asynchronous data sources exist in the web and server-side world. One of them is the simple callback pattern which is frequently used in Node.js. In this design pattern, the arguments are passed to the function, and then a callback is usually the last parameter, which when executed, passes control to the inner scope with the data. Node.js has a standard way of doing callbacks in which the callback is called with the `Error` object first if there is an error, else null, and then the additional parameters from the callback.
## Converting Callbacks to Observable Sequences ##
Many asynchronous methods in Node.js and the many JavaScript APIs are written in such a way that it has a callback as the last parameter. These standard callbacks are executed with the data passed to it once it is available. We can use the [`Rx.Observable.fromCallback`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromcallback.md) to wrap these kinds of callbacks. Note that this does not cover the Node.js style of callbacks where the `Error` parameter is first. For that operation, we provide the [`Rx.Observable.fromNodeCallback`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromnodecallback.md) which we will cover below.
In the following example, we will convert the Node.js [`fs.exists`](http://nodejs.org/api/fs.html#fs_fs_exists_path_callback) function. This function takes a path and returns a `true` or `false` value whether the file exists, in this case we will check if 'file.txt' exists. The arguments returned when wrapped in `Rx.Observable.fromCallback` will return an array containing the arguments passed to the callback.
```js
var Rx = require('rx'),
fs = require('fs');
// Wrap the exists method
var exists = Rx.Observable.fromCallback(fs.exists);
var source = exists('file.txt');
// Get the first argument only which is true/false
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: true
// => onCompleted
```
## Converting Node.js Style Callbacks to Observable Sequences ##
Node.js has adopted a convention in many of the callbacks where an error may occur, such as File I/O, Network requests, etc. RxJS supports this through the [`Rx.Observable.fromNodeCallback`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromnodecallback.md) method in which the error, if present, is captured and the `onError` notification is sent. Otherwise, the `onNext` is sent with the rest of the callback arguments, followed by an `onCompleted` notification.
In the following example, we will convert the Node.js [`fs.rename`](http://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback) function to an Observable sequence.
```js
var fs = require('fs'),
Rx = require('rx');
// Wrap fs.rename
var rename = Rx.Observable.fromNodeCallback(fs.rename);
// Rename file which returns no parameters except an error
var source = rename('file1.txt', 'file2.txt');
var subscription = source.subscribe(
function (x) { console.log('onNext: success!'); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: success!
// => onCompleted
```
## Converting Observable sequences to Callbacks ##
We can easily go in another direction and convert an observable sequence to a callback. This of course requires the observable sequence to yield only one value for this to make sense. Let's convert using the [`timer`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/timer.md) method to wait for a certain amount of time. The implementation of `toCallback` could look like the following. Note that it is not included in RxJS but you can easily add it if needed.
```js
Rx.Observable.prototype.toCallback = function (cb) {
var source = this;
return function () {
var val, hasVal = false;
source.subscribe(
function (x) { hasVal = true; val = x; },
function (e) { throw e; }, // Default error handling
function () { hasVal && cb(val); }
);
};
};
```
Then we could execute our command simply like the following:
```js
function cb (x) { console.log('hi!'); }
setTimeout(
Rx.Observable.timer(5000)
.toCallback(cb)
, 500);
```
## Converting Observable sequences to Node.js Style Callbacks ##
The same could also apply to Node.js style callbacks should you desire that behavior. Once again the same restrictions apply with regards to having a single value and an end much like above. The implementation of `toNodeCallback` could look like the following. Note that it is not included in RxJS but you can easily add it if needed.
```js
Rx.Observable.prototype.toNodeCallback = function (cb) {
var source = this;
return function () {
var val, hasVal = false;
source.subscribe(
function (x) { hasVal = true; val = x; },
function (e) { cb(e); },
function () { hasVal && cb(null, val); }
);
};
};
```
We could then take this and for example if we had an observable sequence which gets a value from a REST call and then convert it to Node.js style.
```js
getData().toNodeCallback(function (err, data) {
if (err) { throw err; }
// Do something with the data
});
```
================================================
FILE: doc/gettingstarted/categories.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Operators by Categories #
This topic lists all major operators implemented by the [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md) type by their categories, specifically: creation, conversion, combine, functional, mathematical, time, exceptions, miscellaneous, selection and primitives.
## Operators by Categories ##
## See Also ##
*Reference*
- [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
*Concepts*
- [Querying Observable Sequences](querying.md)
================================================
FILE: doc/gettingstarted/combining.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
================================================
FILE: doc/gettingstarted/creating.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Creating and Subscribing to Simple Observable Sequences #
You do not need to implement the `Observable` class manually to create an observable sequence. Similarly, you do not need to implement `Observer` either to subscribe to a sequence. By installing the Reactive Extension libraries, you can take advantage of the `Observable` type which provides many operators for you to create a simple sequence with zero, one or more elements. In addition, RxJS provides an overloaded `subscribe` method which allows you to pass in `onNext`, `onError` and `onCompleted` function handlers.
## Creating a sequence from scratch ##
Before getting into many operators, let's look at how to create an `Observable` from scratch using the [`Rx.Observable.create`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/create.md) method.
First, we need to ensure we reference the core `rx.js` file.
```html
```
Or if we're using [Node.js](http://node.js), we can reference it as such:
```js
var Rx = require('rx');
```
In this example, we will simply yield a single value of 42 and then mark it as completed. The return value is completely optional if no cleanup is required.
```js
var source = Rx.Observable.create(function (observer) {
// Yield a single value and complete
observer.onNext(42);
observer.onCompleted();
// Any cleanup logic might go here
return function () {
console.log('disposed');
}
});
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 42
// => onCompleted
subscription.dispose();
// => disposed
```
For most operations, this is completely overkill, but shows the very basics of how most RxJS operators work.
## Creating and subscribing to a simple sequence ##
The following sample uses the [`range`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/range.md) operator of the `Observable` type to create a simple observable collection of numbers. The observer subscribes to this collection using the Subscribe method of the Observable class, and provides actions that are delegates which handle `onNext`, `onError` and `onCompleted`. In our example, it creates a sequence of integers that starts with x and produces y sequential numbers afterwards.
As soon as the subscription happens, the values are sent to the observer. The `onNext` function then prints out the values.
```js
// Creates an observable sequence of 5 integers, starting from 1
var source = Rx.Observable.range(1, 5);
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted
```
When an observer subscribes to an observable sequence, the `subscribe` method may be using asynchronous behavior behind the scenes depending on the operator. Therefore, the `subscribe` call is asynchronous in that the caller is not blocked until the observation of the sequence completes. This will be covered in more details in the [Using Schedulers](schedulers.md) topic.
Notice that the [`subscribe`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/susbcribe.md) method returns a `Disposable`, so that you can unsubscribe to a sequence and dispose of it easily. When you invoke the `dispose` method on the observable sequence, the observer will stop listening to the observable for data. Normally, you do not need to explicitly call `dispose` unless you need to unsubscribe early, or when the source observable sequence has a longer life span than the observer. Subscriptions in Rx are designed for fire-and-forget scenarios without the usage of a finalizer. Note that the default behavior of the Observable operators is to dispose of the subscription as soon as possible (i.e, when an `onCompleted` or `onError` messages is published). For example, the code will subscribe x to both sequences a and b. If a throws an error, x will immediately be unsubscribed from b.
```js
var x = Rx.Observable.zip(a, b, function (a1, b1) { return a1 + b1; }).subscribe();
```
You can also tweak the code sample to use the Create operator of the Observer type, which creates and returns an observer from specified OnNext, OnError, and OnCompleted action delegates. You can then pass this observer to the Subscribe method of the Observable type. The following sample shows how to do this.
```js
// Creates an observable sequence of 5 integers, starting from 1
var source = Rx.Observable.range(1, 5);
// Create observer
var observer = Rx.Observer.create(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// Prints out each item
var subscription = source.subscribe(observer);
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted
```
In addition to creating an observable sequence from scratch, you can convert existing Arrays, events, callbacks and promises into observable sequences. The other topics in this section will show you how to do this.
Notice that this topic only shows you a few operators that can create an observable sequence from scratch. To learn more about other LINQ operators, see Querying Observable Sequences using LINQ Operators.
## Using a timer ##
The following sample uses the [`timer`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/timer.md) operator to create a sequence. The sequence will push out the first value after 5 second has elapsed, then it will push out subsequent values every 1 second. For illustration purpose, we chain the [`timestamp`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/timestamp.md) operator to the query so that each value pushed out will be appended by the time when it is published. By doing so, when we subscribe to this source sequence, we can receive both its value and timestamp.
First, we need to ensure we reference the proper files if in the browser. Note that the RxJS NPM Package already includes all operators by default.
```html
```
Now on to our example
```js
console.log('Current time: ' + Date.now());
var source = Rx.Observable.timer(
5000, /* 5 seconds */
1000 /* 1 second */)
.timestamp();
var subscription = source.subscribe(
function (x) {
console.log(x.value + ': ' + x.timestamp);
});
/* Output may be similar to this */
// Current time: 1382560697820
// 0: 1382560702820
// 1: 1382560703820
// 2: 1382560704820
```
By using the `timestamp` operator, we have verified that the first item is indeed pushed out 5 seconds after the sequence has started, and each item is published 1 second later.
## Converting Arrays and Iterables to an Observable Sequence ##
Using the [`Rx.Observable.from`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/from.md) operator, you can convert an array to observable sequence.
```js
var array = [1,2,3,4,5];
// Converts an array to an observable sequence
var source = Rx.Observable.from(array);
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted
```
You can also convert array-like objects such as objects with a length property and indexed with numbers. In this case, we'll simply have an object with a length of 5.
```js
var arrayLike = { length: 5 };
// Converts an array to an observable sequence
var source = Rx.Observable.from(arrayLike, function (v, k) { return k + 1; });
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted
```
In addition, we can also use ES6 Iterable objects such as `Map` and `Set` using `from` to an observable sequence. In this example, we can take a `Set` and convert it to an observable sequence.
```js
var set = new Set([1,2,3,4,5]);
// Converts a Set to an observable sequence
var source = Rx.Observable.from(set);
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted
```
We can also do a `Map` as well by applying the same technique.
```js
var map = new Map([['key1', 1], ['key2', 2]]);
// Converts a Map to an observable sequence
var source = Rx.Observable.from(map);
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: key1, 1
// => onNext: key2, 2
// => onCompleted
```
The `from` method can also support ES6 generators which may already be in your browser, or coming to a browser near you. This allows us to do such things as Fibonacci sequences and so forth and convert them to an observable sequence.
```js
function* fibonacci () {
var fn1 = 1;
var fn2 = 1;
while (1){
var current = fn2;
fn2 = fn1;
fn1 = fn1 + current;
yield current;
}
}
// Converts a generator to an observable sequence
var source = Rx.Observable.from(fibonacci()).take(5);
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 1
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 5
// => onCompleted
```
## Cold vs. Hot Observables ##
Cold observables start running upon subscription, i.e., the observable sequence only starts pushing values to the observers when Subscribe is called. Values are also not shared among subscribers. This is different from hot observables such as mouse move events or stock tickers which are already producing values even before a subscription is active. When an observer subscribes to a hot observable sequence, it will get all values in the stream that are emitted after it subscribes. The hot observable sequence is shared among all subscribers, and each subscriber is pushed the next value in the sequence. For example, even if no one has subscribed to a particular stock ticker, the ticker will continue to update its value based on market movement. When a subscriber registers interest in this ticker, it will automatically receive the next tick.
The following example demonstrates a cold observable sequence. In this example, we use the Interval operator to create a simple observable sequence of numbers pumped out at specific intervals, in this case, every 1 second.
Two observers then subscribe to this sequence and print out its values. You will notice that the sequence is reset for each subscriber, in which the second subscription will restart the sequence from the first value.
First, we need to ensure we reference the proper files if in the browser. Note that the RxJS NPM Package already includes all operators by default.
```html
```
And now to the example.
```js
var source = Rx.Observable.interval(1000);
var subscription1 = source.subscribe(
function (x) { console.log('Observer 1: onNext: ' + x); },
function (e) { console.log('Observer 1: onError: ' + e.message); },
function () { console.log('Observer 1: onCompleted'); });
var subscription2 = source.subscribe(
function (x) { console.log('Observer 2: onNext: ' + x); },
function (e) { console.log('Observer 2: onError: ' + e.message); },
function () { console.log('Observer 2: onCompleted'); });
setTimeout(function () {
subscription1.dispose();
subscription2.dispose();
}, 5000);
// => Observer 1: onNext: 0
// => Observer 2: onNext: 0
// => Observer 1: onNext: 1
// => Observer 2: onNext: 1
// => Observer 1: onNext: 2
// => Observer 2: onNext: 2
// => Observer 1: onNext: 3
// => Observer 2: onNext: 3
```
In the following example, we convert the previous cold observable sequence source to a hot one using the [`publish`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/publish.md) operator, which returns a `ConnectableObservable` instance we name `hot`. The [`publish`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/publish.md) operator provides a mechanism to share subscriptions by broadcasting a single subscription to multiple subscribers. The `hot` variable acts as a proxy by subscribing to `source` and, as it receives values from `source`, pushing them to its own subscribers. To establish a subscription to the backing source and start receiving values, we use the [`ConnectableObservable.prototype.connect`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/connect.md) method. Since `ConnectableObservable` inherits `Observable`, we can use `subscribe` to subscribe to this hot sequence even before it starts running. Notice that in the example, the hot sequence has not been started when `subscription1` subscribes to it. Therefore, no value is pushed to the subscriber. After calling Connect, values are then pushed to `subscription1`. After a delay of 3 seconds, `subscription2` subscribes to `hot` and starts receiving the values immediately from the current position (3 in this case) until the end. The output looks like this:
```
// => Current time: 1382562433256
// => Current Time after 1st subscription: 1382562433260
// => Current Time after connect: 1382562436261
// => Observer 1: onNext: 0
// => Observer 1: onNext: 1
// => Current Time after 2nd subscription: 1382562439262
// => Observer 1: onNext: 2
// => Observer 2: onNext: 2
// => Observer 1: onNext: 3
// => Observer 2: onNext: 3
// => Observer 1: onNext: 4
// => Observer 2: onNext: 4
```
First, we need to ensure we reference the proper files if in the browser. Note that the RxJS NPM Package already includes all operators by default.
```html
```
Now onto the example!
```js
console.log('Current time: ' + Date.now());
// Creates a sequence
var source = Rx.Observable.interval(1000);
// Convert the sequence into a hot sequence
var hot = source.publish();
// No value is pushed to 1st subscription at this point
var subscription1 = hot.subscribe(
function (x) { console.log('Observer 1: onNext: %s', x); },
function (e) { console.log('Observer 1: onError: %s', e); },
function () { console.log('Observer 1: onCompleted'); });
console.log('Current Time after 1st subscription: ' + Date.now());
// Idle for 3 seconds
setTimeout(function () {
// Hot is connected to source and starts pushing value to subscribers
hot.connect();
console.log('Current Time after connect: ' + Date.now());
// Idle for another 3 seconds
setTimeout(function () {
console.log('Current Time after 2nd subscription: ' + Date.now());
var subscription2 = hot.subscribe(
function (x) { console.log('Observer 2: onNext: %s', x); },
function (e) { console.log('Observer 2: onError: %s', e); },
function () { console.log('Observer 2: onCompleted'); });
}, 3000);
}, 3000);
```
**Analogies**
It helps to think of cold and hot Observables as movies or performances that one can watch ("subscribe").
- Cold Observables: movies.
- Hot Observables: live performances.
- Hot Observables replayed: live performances recorded on video.
Whenever you watch a movie, your run of the movie is independent of anyone else's run, even though all movie watchers see the same effects. On the other hand, a live performance is shared to multiple viewers. If you arrive late to a live performance, you will simply miss some of it. However, if it was recorded on video (in RxJS this would happen with a BehaviorSubject or a ReplaySubject), you can watch a "movie" of the live performance. A [`.publish().refCount()`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/refcount.md) live performance is one where the artists quit playing when no one is watching, and start playing again when there is at least one person in the audience.
================================================
FILE: doc/gettingstarted/creatingquerying.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Creating and Querying Observable Sequences #
This section describes how you can create and subscribe to an observable sequence, convert an existing JavaScript event and query it.
1. [Creating and Subscribing to Simple Observable Sequences](creating.md)
2. [Bridging to Events](events.md)
3. [Bridging to Callbacks and Promises](callbacks.md)
4. [Querying Observable Sequences](querying.md)
5. [Operators by Category](categories.md)
================================================
FILE: doc/gettingstarted/errors.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Error Handling in the Reactive Extensions #
One of the most difficult tasks in asynchronous programming is dealing with errors. Unlike interactive style programming, we cannot simply use the try/catch/finally approach that we use when dealing with blocking code.
```js
try {
for (var obj in objs) {
doSomething(obj);
}
} catch (e) {
handleError(e);
} finally {
doCleanup();
}
```
These actions mirror exactly our `Observer` class which has the following contract for handing zero to infinite items with `onNext` and optionally handling either an `Error` with `onError` or successful completion with `onCompleted`.
```typescript
interface Observable {
onNext(value: T) : void
onError(error: Error) : void
onCompleted() : void
}
```
But the try/catch/finally approach won't work with asynchronous code. Instead, we have a myriad of ways of handling errors as they occur, and ensure proper disposal of resources.
For example, we might want to do the following:
- swallow the error and switch over to a backup Observable to continue the sequence
- swallow the error and emit a default item
- swallow the error and immediately try to restart the failed Observable
- swallow the error and try to restart the failed Observable after some back-off interval
We'll cover each of those scenarios and more in this section.
## Catching Errors ##
The first topic is catching errors as they happen with our streams. In the Reactive Extensions, any error is propogated through the `onError` channel which halts the sequence. We can compensate for this by using the `catch` operator, at both the class and instance level.
Using the class level `catch` method, we can catch errors as they happen with the current sequence and then move to the next sequence should there be an error. For example, we could try getting data from several URLs, it doesn't matter which since they all have the same data, and then if that fails, default to a cached version, so an error should never propagate. One thing to note is that if `get('url')` calls succeed, then it will not move onto the next sequence in the list.
```js
var source = Rx.Observable.catch(
get('url1'),
get('url2'),
get('url3'),
getCachedVersion()
);
var subscription = source.subscribe(
function (data) {
// Display the data as it comes in
}
);
```
We also have an instance version of `catch` which can be used two ways. The first way is much like the example above, where we can take an existing stream, catch the error and move onto the next stream or `Promise`.
```js
var source = get('url1').catch(getCachedVersion());
var subscription = source.subscribe(
function (data) {
// Display the data as it comes in
}
);
```
The other overload of `catch` allows us to inspect the error as it comes in so we can decide which route to take. For example, if an error status code of 500 comes back from our web server, we can assume it is down and then use a cached version.
```js
var source = get('url1').catch(function (e) {
if (e.status === 500) {
return cachedVersion();
} else {
return get('url2');
}
});
var subscription = source.subscribe(
function (data) {
// Display the data as it comes in
}
);
```
This isn't the only way to handle errors as there are plenty of others as you'll see below.
## Ignoring Errors with `onErrorResumeNext` ##
The Reactive Extensions borrowed from a number of languages in our design. One of those features is bringing [`On Error Resume Next`](https://msdn.microsoft.com/en-us/library/5hsw66as.aspx) from Microsoft Visual Basic. This operation specifies that when a run-time error occurs, control goes to the statement immediately following the statement where the error occurred, and execution continues from that point. There are some instances with stream processing that you simply want to skip a stream which produces an error and move to the next stream. We can achieve this with a class based and instance based `onErrorResumeNext` method.
The class based `onErrorResumeNext` continues a stream that is terminated normally or by an `Error` with the next stream or `Promise`. Unlike `catch`, `onErrorResumeNext` will continue to the next sequence regardless of whether the previous was in error or not. To make this more concrete, let's use a simple example of mixing error sequences with normal sequences.
```js
var source = Rx.Observable.onErrorResumeNext(
Rx.Observable.just(42),
Rx.Observable.throw(new Error()),
Rx.Observable.just(56),
Rx.Observable.throw(new Error()),
Rx.Observable.just(78)
);
var subscription = source.subscribe(
function (data) {
console.log(data);
}
);
// => 42
// => 56
// => 78
```
The instance based `onErrorResumeNext` is similar to the class based version, the only difference being that it is attached to the prototype, but can take another sequence or `Promise` and continue.
## Retrying Sequences ##
When catching errors isn't enough and we want to retry our logic, we can do so with `retry` or `retryWhen` operators. With the `retry` operator, we can try a certain operation a number of times before an error is thrown. This is useful when you need to get data from a resource which may have intermittent failures due to load or any other issue.
Let's take a look at a simple example of trying to get some data from a URL and giving up after three tries.
```js
// Try three times to get the data and then give up
var source = get('url').retry(3);
var subscription = source.subscribe(
function (data) {
console.log(data);
},
function (err) {
console.log(err);
}
);
```
In the above example, it will give up after three tries and thus call `onError` if it continues to fail after the third try. We can remedy that by adding `catch` to use an alternate source.
```js
// Try three times to get the data and then return cached data if still fails
var source = get('url').retry(3).catch(cachedVersion());
var subscription = source.subscribe(
function (data) {
// Displays the data from the URL or cached data
console.log(data);
}
);
```
The above case retries immediately upon failure. But what if you want to control when a retry happens? We have the `retryWhen` operator which allows us to deeply control when the next try happens. We incrementally back off trying again by using the following method:
```js
var source = get('url').retryWhen(
function (attempts) {
return attempts
.zip(Rx.Observable.range(1, 3), function (_, i) { return i })
.flatMap(function (i) {
console.log('delay retry by ' + i + ' second(s)');
return Rx.Observable.timer(i * 1000);
});
}
);
var subscription = source.subscribe(
function (data) {
// Displays the data from the URL or cached data
console.log(data);
}
);
// => delay retry by 1 second(s)
// => delay retry by 2 second(s)
// => Data
```
## Ensuring Cleanup with Finally ##
We've already covered the try/catch part of try/catch/finally, so what about finally? We have the `finally` operator which calls a function after the source sequence terminates gracefully or exceptionally. This is useful if you are using external resources or need to free up a particular variable upon completion.
In this example, we can ensure that our `WebSocket` will indeed be closed once the last message is processed.
```js
var socket = new WebSocket('ws://someurl', 'xmpp');
var source = Rx.Observable.from(data)
.finally(function () { socket.close(); });
var subscription = source.subscribe(
function (data) {
socket.send(data);
}
);
```
But,we can do a better job in terms of managing resources if need be by using the `using` method.
## Ensuring Resource Disposal ##
As stated above, `finally` can be used to ensure proper cleanup of any resources or perform any side effects as necessary. There is a cleaner approach we can take by creating a disposable wrapper around our object with a `dispose` method so that when our scope is complete, then the resource is automatically disposed through the `using` operator.
```js
function DisposableWebSocket(url, protocol) {
var socket = new WebSocket(url, protocol);
// Create a way to close the WebSocket upon completion
var d = Rx.Disposable.create(function () {
socket.close();
});
d.socket = socket;
return d;
}
var source = Rx.Observable.using(
function () { return new DisposableWebSocket('ws://someurl', 'xmpp'); },
function (d) {
return Rx.Observable.from(data)
.tap(function (data) { d.socket.send(data); });
}
);
var subscription = source.subscribe();
```
## Delaying Errors with `mergeDelayError` ##
Another issue may arise when you are dealing with flattening sequences into a single sequence and there may be errors along the way. We want a way to flatten without being interrupted by one of our sources being in error. This is much like the other operator `mergeAll` but the main difference is, instead of immediately bubbling up the error, it holds off until the very end.
To illustrate, we can create this little sample that has an errored sequence in the middle when it is trying to flatten the sequences.
```js
var source1 = Rx.Observable.of(1,2,3);
var source2 = Rx.Observable.throwError(new Error('woops'));
var source3 = Rx.Observable.of(4,5,6);
var source = Rx.Observable.mergeDelayError(source1, source2, source3);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => 1
// => 2
// => 3
// => 4
// => 5
// => 6
// => Error: Error: woops
```
## Further Reading ##
- [Using Generators For Try/Catch Operations](generators.md)
- [Testing and Debugging Your RxJS Application](testing.md)
================================================
FILE: doc/gettingstarted/events.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Bridging to Events #
RxJS provides factory methods for you to bridge with existing asynchronous sources in the DOM or Node.js so that you can employ the rich composing, filtering and resource management features provided by RxJS on any kind of data streams. This topic examines the [`fromEvent`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromevent.md) and [`fromEventPattern`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromeventpattern.md) operator that allows "importing" a DOM or custom event into RxJS as an observable sequence. Every time an event is raised, an `onNext` message will be delivered to the observable sequence. You can then manipulate event data just like any other observable sequences.
RxJS does not aim at replacing existing asynchronous programming models such as promises or callbacks. However, when you attempt to compose events, RxJS’s factory methods will provide you the convenience that cannot be found in the current programming model. This is especially true for resource maintenance (e.g., when to unsubscribe) and filtering (e.g., choosing what kind of data to receive). In this topic and the ones that follow, you can examine how these RxJS features can assist you in asynchronous programming.
Natively, RxJS supports a number of libraries and hooks into them such as [jQuery](http://jquery.com/), [Zepto.js](http://zeptojs.com/), [AngularJS](https://angularjs.org/), [Ember.js](http://emberjs.com/) and [Backbone.js](http://backbonejs.org) for using their event system. This behavior, however, can be overridden to only use native bindings only. By default, RxJS also has hooks for [Node.js](http://nodejs.org) `EventEmitter` events natively supported.
## Converting a DOM event to a RxJS Observable Sequence ##
The following sample creates a simple DOM event handler for the mouse move event, and prints out the mouse’s location on the page.
```js
var result = document.getElementById('result');
document.addEventListener('mousemove', function (e) {
result.innerHTML = e.clientX + ', ' + e.clientY;
}, false);
```
To import an event into RxJS, you can use the [`fromEvent`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromevent.md) operator, and provide the event arguments that will be raised by the event being bridged. It then converts the given event into an observable sequence.
In the following example, we convert the mousemove event stream of the DOM into an observable sequence. Every time a mouse-move event is fired, the subscriber will receive an `onNext` notification. We can then examine the event arguments value of such notification and get the location of the mouse-move.
```js
var result = document.getElementById('result');
var source = Rx.Observable.fromEvent(document, 'mousemove');
var subscription = source.subscribe(function (e) {
result.innerHTML = e.clientX + ', ' + e.clientY;
});
```
Notice that in this sample, move becomes an observable sequence in which we can manipulate further. The [Querying Observable Sequences](querying.md) topic will show you how you can project this sequence into a collection of Points type and filter its content, so that your application will only receive values that satisfy a certain criteria.
Cleaning up of the event handler is taken care of by the `Disposable` object returned by the `subscribe` method. Calling `dispose` will release all resources being used by the sequence including the underlying event handler. This essentially takes care of unsubscribing to an event on your behalf.
The `fromEvent` method also supports adding event handlers to multiple items, for example a DOM NodeList. This example will add the 'click' to each element in the list.
```js
var result = document.getElementById('result');
var sources = document.querySelectorAll('div');
var source = Rx.Observable.fromEvent(sources, 'click');
var subscription = source.subscribe(function (e) {
result.innerHTML = e.clientX + ', ' + e.clientY;
});
```
In addition, `fromEvent` also supports libraries such as [jQuery](http://jquery.com/), [Zepto.js](http://zeptojs.com/), [AngularJS](https://angularjs.org/), [Ember.js](http://emberjs.com/) and [Backbone.js](http://backbonejs.org):
```js
var $result = $('#result');
var $sources = $('div');
var source = Rx.Observable.fromEvent($sources, 'click');
var subscription = source.subscribe(function (e) {
$result.html(e.clientX + ', ' + e.clientY);
});
```
If this behavior is not desired, you can override it by setting the `Rx.config.useNativeEvents` to `true` which will disregard any library for which we support events.
```js
// Use only native events even if jQuery
Rx.config.useNativeEvents = true;
// Native events only
var result = document.getElementById('result');
var source = Rx.Observable.fromEvent(document, 'mousemove');
var subscription = source.subscribe(function (e) {
result.innerHTML = e.clientX + ', ' + e.clientY;
});
```
In addition, you could easily add many shortcuts into the event system for events such as `mousemove`, and even extending to [Pointer](http://www.w3.org/TR/pointerevents/) and [Touch](http://www.w3.org/TR/touch-events/) Events.
```js
Rx.dom = {};
var events = "blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu";
if (root.PointerEvent) {
events += " pointerdown pointerup pointermove pointerover pointerout pointerenter pointerleave";
}
if (root.TouchEvent) {
events += " touchstart touchend touchmove touchcancel";
}
events.split(' ').forEach(function (e) {
Rx.dom[e] = function (element, selector) {
return Rx.Observable.fromEvent(element, e, selector);
};
});
```
Now we can rewrite a simple mouse drag as the following:
```js
var draggable = document.getElementById('draggable');
var mousedrag = Rx.dom.mousedown(draggable).flatMap(function (md) {
md.preventDefault();
var start = getLocation(md);
return Rx.dom.mousemove(document)
.map(function (mm) {
return getDelta(start, mm);
})
.takeUntil(Rx.dom.mouseup(draggable));
});
```
Note this is already available in the [RxJS-DOM](https://github.com/Reactive-Extensions/RxJS-DOM) project, but is small enough for you to implement yourself.
## Converting a Node.js event to a RxJS Observable Sequence ##
Node.js is also supported such as an [`EventEmitter`](http://nodejs.org/api/events.html#events_class_events_eventemitter):
```js
var Rx = require('rx'),
EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var source = Rx.Observable.fromEvent(eventEmitter, 'data')
var subscription = source.subscribe(function (data) {
console.log('data: ' + data);
});
eventEmitter.emit('data', 'foo');
// => data: foo
```
## Bridging to Custom Events with FromEventPattern ##
There may be instances dealing with libraries which have different ways of subscribing and unsubscribing from events. The [`fromEventPattern`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/fromeventpattern.md) method was created exactly for this purpose to allow you to bridge to each of these custom event emitters.
For example, you might want to bridge to using jQuery [`on`](http://api.jquery.com/on/) method. We can convert the following code which alerts based upon the click of a table row.
```js
$( "#dataTable tbody" ).on('click', 'tr', function() {
alert( $( this ).text() );
});
```
The converted code looks like this while using the `fromEventPattern` method. Each function passes in the handler function which allows you to call the `on` and `off` methods to properly handle disposal of events.
```js
var $tbody = $('#dataTable tbody');
var source = Rx.Observable.fromEventPattern(
function addHandler (h) { $tbody.on('click', 'tr', h); },
function delHandler (h) { $tbody.off('click', 'tr', h); });
var subscription = source.subscribe(function (e) {
alert( $(e.target).text() );
});
```
In addition to this normal support, we also support if the `addHandler` returns an object, it can be passed to the `removeHandler` to properly unsubscribe. In this example, we'll use the [Dojo Toolkit](http://dojotoolkit.org) and the [`on`](http://dojotoolkit.org/api/1.9/dojo/on.html) module.
```js
require(['dojo/on', 'dojo/dom', 'rx', 'rx.async', 'rx.binding'], function (on, dom, rx) {
var input = dom.byId('input');
var source = Rx.Observable.fromEventPattern(
function addHandler (h) {
return on(input, 'click', h);
},
function delHandler (_, signal) {
signal.remove();
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: Clicked!');
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
on.emit(input, 'click');
// => Next: Clicked!
});
```
## See Also
Concepts
- [Querying Observable Sequences](querying.md)
================================================
FILE: doc/gettingstarted/exploring.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Exploring The Major Concepts in RxJS #
This topic describes the major Reactive Extensions for JavaScript (Rx) objects used to represent observable sequences and subscribe to them.
The `Observable` / `Observer` objects are available in the core distribution of RxJS.
## `Observable` / `Observer` ##
Rx exposes asynchronous and event-based data sources as push-based, observable sequences abstracted by the [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md) object in the core distribution of RxJS. It represents a data source that can be observed, meaning that it can send data to anyone who is interested.
As described in [What is RxJS](what.md), the other half of the push model is represented by the [`Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md) object, which represents an observer who registers an interest through a subscription. Items are subsequently handed to the observer from the observable sequence to which it subscribes.
In order to receive notifications from an observable collection, you use the [`subscribe`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypesubscribeobserver--onnext-onerror-oncompleted) method of `Observable` to hand it an `Observer` object. In return for this observer, the [`subscribe`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypesubscribeobserver--onnext-onerror-oncompleted) method returns a `Disposable` object that acts as a handle for the subscription. This allows you to clean up the subscription after you are done. Calling `dispose` on this object detaches the observer from the source so that notifications are no longer delivered. As you can infer, in RxJS you do not need to explicitly unsubscribe from an event as in the common JavaScript event model.
Observers support three publication events, reflected by the object's methods. The [`onNext`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md#rxobserverprototypeonnextvalue) can be called zero or more times, when the observable data source has data available. For example, an observable data source used for mouse move events can send out an event object every time the mouse has moved. The other two methods are used to indicate completion or errors.
The following lists the `Observable` / `Observer` objects in addition to the `Disposable` object.
```js
/**
* Defines a method to release allocated resources.
*/
function Disposable() { }
/**
* Performs application-defined tasks associated with freeing, releasing, or resetting resources.
*/
Disposable.prototype.dispose = function () { ... }
/**
* Defines a provider for push-based notification.
*/
function Observable() { }
/**
* Notifies the provider that an observer is to receive notifications.
*
* @param {Observer} observer The object that is to receive notifications.
* @returns {Disposable} A reference to disposable that allows observers to stop receiving notifications before the provider has finished sending them.
*/
Observable.prototype.subscribe = function (observer) { ... }
/**
* Provides a mechanism for receiving push-based notifications.
*/
function Observer() { }
/**
* Provides the observer with new data.
*
* @param {Any} value The current notification information.
*/
Observer.prototype.onNext = function (value) { ... };
/**
* Notifies the observer that the provider has experienced an error condition.
*
* @param {Error} error An object that provides additional information about the error.
*/
Observer.prototype.onError = function (error) { ... };
/**
* Notifies the observer that the provider has finished sending push-based notifications.
*/
Observer.prototype.onCompleted = function () { ... };
```
RxJS also provides `subscribe` capabilities so that you can avoid implementing the `Observer` object yourself. For each publication event (`onNext`, `onError`, `onCompleted`) of an observable sequence, you can specify a function that will be invoked, as shown in the following example. If you do not specify an action for an event, the default behavior will occur.
```js
// Creates an observable sequence of 5 integers, starting from 1
var source = Rx.Observable.range(1, 5);
// Prints out each item
var subscription = source.subscribe(
function (x) { console.log('onNext: ' + x); },
function (e) { console.log('onError: ' + e.message); },
function () { console.log('onCompleted'); });
// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted
```
You can treat the observable sequence (such as a sequence of mouse-over events) as if it were a normal collection. Thus you can write queries over the collection to do things like filtering, grouping, composing, etc. To make observable sequences more useful, the RxJS libraries provide many factory operators so that you do not need to implement any of these on your own. This will be covered in the [Querying Observable Sequences](querying.md) topic.
### Caution:
You do not need to implement the Observable/Observer objects yourself. Rx provides internal implementations of these interfaces for you and exposes them through various extension methods provided by the Observable and Observer types. See the [Creating and Querying Observable Sequences](creatingquerying.md) topic for more information.
### See Also
Concepts
- [Querying Observable Sequences](querying.md)
Other Resources
- [Creating and Querying Observable Sequences](creatingquerying.md)
================================================
FILE: doc/gettingstarted/generators.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Generators and Observable Sequences #
One of the more exciting features of ES6 is a new function type called generators. They have been in Firefox for years, although they have now been finally standardized in ES6, and will be shipping in a browser or runtime near you. How generators differ from normal functions is that a normal function such as the following will run to completion, regardless of whether it is asynchronous or not.
```js
function printNumberOfTimes(msg, n) {
for (var i = 0; i < n; i++) {
console.log(msg);
}
}
printNumberOfTime('Hello world', 1);
// => Hello world
// Asynchronous
setTimeout(function () {
console.log('Hello from setTimeout after one second');
}, 1000);
// => Hello from setTimeout after one second
```
Instead of running to completion, generators allow us to interrupt the flow of the function by introducing the `yield` keyword which pauses the function. The function cannot resume on its own without the external consumer saying that they need the next value.
To create a generator function, you must use the `function*` syntax which then becomes a generator. In this particular example, we will yield a single value, the meaning of life.
```js
function* theMeaningOfLife() {
yield 42;
}
```
To get the value out, we need to invoke the function, and then call `next` to get the next value. The return value from the `next` call will have a flag as to whether it is done, as well as any value that is yielded. Note that the function doesn't do anything until we start to call `next`.
```js
var it = theMeaningOfLife();
it.next();
// => { done: false, value: 42 }
it.next();
// => { done: true, value: undefined }
```
We can also use some ES6 shorthand for getting values from a generator such as the `for..of`.
```js
for (var v of theMeaningOfLife()) {
console.log(v);
}
// => 42
```
This of course is only scratching the surface of what generators are capable of doing as we're more focused on the simple nature of yielding values.
Since RxJS believes heavily in standards, we also look for ways to incorporate new language features as they become standardized so that you can take advantage of them, combined with the power of RxJS.
## Async/Await Style and RxJS ##
One common complaint of JavaScript is the callback nature to asynchronous behavior. Luckily, this can be solved quite easily with a library approach. To that end, we introduce [`Rx.spawn`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/spawn.md) which allows you to write straight forward code manner and can yield not only Observable sequences, but also Promises, Callbacks, Arrays, etc. This allows you to write your code in a very imperative manner without all the callbacks, but also brings the power of RxJS whether you want to call `timeout`, `retry`, `catch` or any other method for that matter. Note that this only yields a single value, but in RxJS terms, this is still quite useful.
For example, we could get the HTML from Bing.com and write it to the console, with a timeout of 5 seconds which will throw an error should it not respond in time. We could also add in things like `retry` and `catch` so that we could for example try three times and then if it fails, give a default response or cached version.
```js
var Rx = require('rx');
var request = require('request');
var get = Rx.Observable.fromNodeCallback(request);
Rx.Observable.spawn(function* () {
var data;
try {
data = yield get('http://bing.com').timeout(5000 /*ms*/);
} catch (e) {
console.log('Error %s', e);
}
console.log(data);
}).subscribe();
```
## Mixing Operators with Generators ##
Many of the operators inside RxJS also support generators. For example, we could use the [`Rx.Observable.from`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/from.md) method to take a generator function, in this case, a Fibonacci sequence, take 10 of them and display it.
```js
function* fibonacci(){
var fn1 = 1;
var fn2 = 1;
while (1) {
var current = fn2;
fn2 = fn1;
fn1 = fn1 + current;
yield current;
}
}
Rx.Observable.from(fibonacci())
.take(10)
.subscribe(function (x) {
console.log('Value: %s', x);
});
//=> Value: 1
//=> Value: 1
//=> Value: 2
//=> Value: 3
//=> Value: 5
//=> Value: 8
//=> Value: 13
//=> Value: 21
//=> Value: 34
//=> Value: 55
```
That's just the beginning, as there are several operators such as [`concatMap`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concatmap.md)/[`selectConcat`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concatmap.md) and [`flatMap`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/selectmany.md)/[`selectMany`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concatmap.md) which take iterables as an argument so that we can further enable composition. For example, we could project using generators from a `flatMap` operation.
```js
var source = Rx.Observable.of(1,2,3)
.flatMap(
function (x, i) { return function* () { yield x; yield i; }(); },
function (x, y, i1, i2) { return x + y + i1 + i2; }
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
// => Next: 2
// => Next: 2
// => Next: 5
// => Next: 5
// => Next: 8
// => Next: 8
// => Completed
```
The future of JavaScript is exciting and generators add new possibilities to our applications to allow them to mix and match our programming styles.
Notice that in this sample, move becomes an observable sequence in which we can manipulate further. The [Querying Observable Sequences](querying.md) topic will show you how you can project this sequence into a collection of Points type and filter its content, so that your application will only receive values that satisfy a certain criteria.
## See Also
Concepts
- [Querying Observable Sequences](querying.md)
================================================
FILE: doc/gettingstarted/operators.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Implementing Your Own Observable Operators #
You can extend RxJS by adding new operators for operations that are not provided by the base library, or by creating your own implementation of standard query operators to improve readability and performance. Writing a customized version of a standard operator is useful when you want to operate with in-memory objects and when the intended customization does not require a comprehensive view of the query.
## Creating New Operators ##
RxJS offers a full set of operators that cover most of the possible operations on a set of entities. However, you might need an operator to add a particular semantic meaning to your query—especially if you can reuse that same operator several times in your code. Adding new operators to RxJS is a way to extend its capabilities. However, you can also improve code readability by wrapping existing operators into more specialized and meaningful ones.
For example, let's see how we might implement the [_.where](http://lodash.com/docs#where) method from [Lo-Dash](http://lodash.com/) or [Underscore](http://underscorejs.org/), which takes a set of attributes and does a deep comparison for equality. We might try implementing this from scratch using the `Rx.Observable.create` method such as the following code.
```js
Rx.Observable.prototype.filterByProperties = function (properties) {
var source = this,
comparer = Rx.internals.isEqual;
return Rx.Observable.create(function (observer) {
// Our disposable is the subscription from the parent
return source.subscribe(
function (data) {
try {
var shouldRun = true;
// Iterate the properties for deep equality
for (var prop in properties) {
if (!comparer(properties[prop], data[prop])) {
shouldRun = false;
break;
}
}
} catch (e) {
observer.onError(e);
}
if (shouldRun) {
observer.onNext(data);
}
},
observer.onError.bind(observer),
observer.onCompleted.bind(observer)
);
});
};
```
Many existing operators, such as this, instead could be built using other basic operators for example in this case, `filter` or `where`. In fact, many existing operators are built using other basic operators. For example, the `flatMap` or `selectMany` operator is built by composing the `map` or `select` and `mergeObservable` operators, as the following code shows.
```js
Rx.Observable.prototype.flatMap = function (selector) {
return this.map(selector).mergeObservable();
};
```
We could rewrite it as the following to take advantage of already built in operators.
```js
Rx.Observable.prototype.filterByProperties = function (properties) {
var comparer = Rx.internals.isEqual;
return this.filter(function (data) {
// Iterate the properties for deep equality
for (var prop in properties) {
if (!comparer(properties[prop], data[prop])) {
return false;
}
}
return true;
});
};
```
By reusing existing operators when you build a new one, you can take advantage of the existing performance or exception handling capabilities implemented in the RxJS libraries. When writing a custom operator, it is good practice not to leave any disposables unused; otherwise, you may find that resources could actually be leaked and cancellation may not work correctly.
## Testing Your New Operator ##
Just because you have implemented a new operator doesn't mean you are finished. Now, let's write a test to verify its behavior from what we learned in the [Testing and Debugging](testing.md) topic. We'll reuse the `collectionAssert.assertEqual` from the previous topic so it is not repeated here.
```js
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted,
subscribe = Rx.ReactiveTest.subscribe;
test('filterProperties should yield with match', function () {
var scheduler = new Rx.TestScheduler();
var input = scheduler.createHotObservable(
onNext(210, { 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }),
onNext(220, { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }),
onCompleted(230)
);
var results = scheduler.startWithCreate(
function () {
return input.filterByProperties({ 'age': 40 });
}
);
collectionAssert.assertEqual(results.messages, [
onNext(220, { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }),
onCompleted(230)
]);
collectionAssert.assertEqual(input.subscriptions, [
subscribe(200, 230)
]);
});
```
In order for this to be successfully tested, we should check for when there is no data, empty, single matches, multiple matches and so forth.
## See Also ##
**Resources**
- [Testing and Debugging](testing.md)
================================================
FILE: doc/gettingstarted/promises.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Bridging to Promises #
Promises are a defacto standard within JavaScript community and is part of the ECMAScript Standard. A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled. You can create them very easily where the constructor has two functions, `resolve` and `reject` which resolves the value or rejects it for a given reason. RxJS is fully committed to standards and has native support for Promises for any number of methods where they can be used interchangeably with Observable sequences.
The advantage that you get when you intermix Promises with Observable sequences is that unlike the ES6 Promise standard, you get cancellation semantics which means you can disregard values if you no longer are interested. One of the biggest problems around Promises right now are around cancellation, as to cancel the operation, such as an XHR is not easily done with the existing standard, nor is it to only get the last value to ensure no out of order requests. With Observable sequences, you get that behavior for free in a multicast behavior, instead of the unicast Promise behavior.
The following list of operators natively support Promises:
- [`Rx.Observable.amb`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/amb.md) | [`Rx.Observable.prototype.amb`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/ambproto.md)
- [`Rx.Observable.case`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/case.md)
- [`Rx.Observable.catch`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/catch.md) | [`Rx.Observable.prototype.catch`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/catchproto.md)
- [`Rx.Observable.combineLatest`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/combinelatest.md) | [`Rx.Observable.prototype.combineLatest`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/combinelatestproto.md)
- [`Rx.Observable.concat`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concat.md) | [`Rx.Observable.prototype.concat`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concatproto.md)
- [`Rx.Observable.prototype.concatMap`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concatmap.md)
- [`Rx.Observable.prototype.concatMapObserver`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/concatobserver.md)
- [`Rx.Observable.defer`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/defer.md)
- [`Rx.Observable.prototype.flatMap`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/selectmany.md)
- [`Rx.Observable.prototype.flatMapLatest`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/flatmaplatest.md)
- [`Rx.Observable.forkJoin`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/forkjoin.md) | [`Rx.Observable.prototype.forkJoin`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/forkjoinproto.md)
- [`Rx.Observable.if`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/if.md)
- [`Rx.Observable.merge`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/merge.md)
- [`Rx.Observable.prototype.mergeAll`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/mergeall.md)
- [`Rx.Observable.onErrorResumeNext`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/onerrorresumenext.md) | [`Rx.Observable.prototype.onErrorResumeNext`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/onerrorresumenextproto.md)
- [`Rx.Observable.prototype.selectMany`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/selectmany.md)
- [`Rx.Observable.prototype.selectSwitch`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/flatmaplatest.md)
- [`Rx.Observable.prototype.sequenceEqual`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/sequenceequal.md)
- [`Rx.Observable.prototype.skipUntil`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/skipuntil.md)
- [`Rx.Observable.startAsync`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/startasync.md)
- [`Rx.Observable.prototype.switch`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/switch.md)
- [`Rx.Observable.prototype.takeUntil`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/takeuntil.md)
- [`Rx.Observable.prototype.debounceWithSelector`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/debouncewithselector.md)
- [`Rx.Observable.prototype.timeoutWithSelector`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/timeoutwithselector.md)
- [`Rx.Observable.while`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/while.md)
- [`Rx.Observable.prototype.window`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/window.md)
- [`Rx.Observable.withLatestFrom`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/withlatestfrom.md)
- [`Rx.Observable.zip`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/zip.md) | [`Rx.Observable.prototype.zip`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/zipproto.md)
Because of this, we can now do a number of very interesting things such as combining Promises and Observable sequences.
```js
var source = Rx.Observable.range(0, 3)
.flatMap(function (x) { return Promise.resolve(x * x); });
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 0
// => onNext: 1
// => onNext: 4
// => onCompleted
```
This is just scratching the surface of what Promises and RxJS can do together so that we have first class single values and first class multiple values working together.
## Converting Promises to Observable Sequences ##
It's quite simple to convert a Promise object which conforms to the ES6 Standard Promise where the behavior is uniform across implementations. To support this, we provide the [`Rx.Observable.fromPromise`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/frompromise.md) method which calls the `then` method of the promise to handle both success and error cases.
In the following example, we create promise objects using [RSVP](https://github.com/tildeio/rsvp.js) library.
```js
// Create a promise which resolves 42
var promise1 = new RSVP.Promise(function (resolve, reject) {
resolve(42);
});
var source1 = Rx.Observable.fromPromise(promise1);
var subscription1 = source1.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onNext: 42
// => onCompleted
// Create a promise which rejects with an error
var promise2 = new RSVP.Promise(function (resolve, reject) {
reject(new Error('reason'));
});
var source2 = Rx.Observable.fromPromise(promise2);
var subscription2 = source2.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
// => onError: reject
```
Notice that in this sample, these promises becomes an observable sequences in which we can manipulate further. The [Querying Observable Sequences](querying.md) topic will show you how you can project this sequence into another, filter its content, so that your application will only receive values that satisfy a certain criteria.
## Converting Observable Sequences to Promises ##
Just as you can convert a Promise to an Observable sequence, you can also convert an Observable sequence to a Promise. This either requires native support for Promises, or a Promise library you can add yourself, such as [Q](https://github.com/kriskowal/q), [RSVP](https://github.com/tildeio/rsvp.js), [when.js](https://github.com/cujojs/when) among others. These libraries must conform to the ES6 standard for construction where it provides two functions to resolve or reject the promise.
```js
var p = new Promise(function (resolve, reject) {
resolve(42);
});
```
We can use the [`toPromise`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/topromise.md) method which allows you to convert an Observable sequence to a Promise. This method accepts a Promise constructor, and if not provided, will default to a default implementation. In this first example, we will use [RSVP](https://github.com/tildeio/rsvp.js) to construct our Promise objects.
```js
// Return a single value
var source1 = Rx.Observable.just(1).toPromise(RSVP.Promise);
source1.then(
function (value) {
console.log('Resolved value: %s', value);
},
function (reason) {
console.log('Rejected reason: %s', reason);
});
// => Resolved value: 1
// Reject the Promise
var source2 = Rx.Observable.throwError(new Error('reason')).toPromise(RSVP.Promise);
source2.then(
function (value) {
console.log('Resolved value: %s', value);
},
function (reason) {
console.log('Rejected reason: %s', reason);
});
// => Rejected reason: Error: reason
```
If an implementation is not given with the [`toPromise`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/topromise.md) method, it will fall back to the Promise implementation specified in the `Rx.config.Promise` field. By default this will be set to the runtime's ES6 Promise implementation, but can easily be overridden by specifying the configuration information.
```js
Rx.config.Promise = RSVP.Promise;
var source1 = Rx.Observable.just(1).toPromise();
source1.then(
function (value) {
console.log('Resolved value: %s', value);
},
function (reason) {
console.log('Rejected reason: %s', reason);
});
// => Resolved value: 1
```
If you are in a pure ES6 environment, this should just work without any settings on your part as it will use the runtime's ES6 Promise implementation.
```js
var source1 = Rx.Observable.just(1).toPromise();
source1.then(
function (value) {
console.log('Resolved value: %s', value);
},
function (reason) {
console.log('Rejected reason: %s', reason);
});
// => Resolved value: 1
```
Concepts
- [Querying Observable Sequences](querying.md)
================================================
FILE: doc/gettingstarted/querying.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Querying Observable Sequences #
In [Bridging to Events](events.md), we have converted existing DOM and Node.js events into observable sequences to subscribe to them. In this topic, we will look at the first-class nature of observable sequences as IObservable objects, in which generic LINQ operators are supplied by the Rx assemblies to manipulate these objects. Most operators take an observable sequence and perform some logic on it and output another observable sequence. In addition, as you can see from our code samples, you can even chain multiple operators on a source sequence to tweak the resulting sequence to your exact requirement.
## Using Different Operators ##
We have already used the [`create`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablecreatesubscribe) and [`range`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablerangestart-count-scheduler) operators in previous topics to create and return simple sequences. We have also used the [`fromEvent`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablefromeventelement-eventname) and [`fromEventPattern`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablefromeventpatternaddhandler-removehandler) operators to convert existing events into observable sequences. In this topic, we will use other operators of the `Observable` type so that you can filter, group and transform data. Such operators take observable sequence(s) as input, and produce observable sequence(s) as output.
## Combining different sequences ##
In this section, we will examine some of the operators that combine various observable sequences into a single observable sequence. Notice that data are not transformed when we combine sequences.
In the following sample, we use the Concat operator to combine two sequences into a single sequence and subscribe to it. For illustration purpose, we will use the very simple `range(x, y)` operator to create a sequence of integers that starts with x and produces y sequential numbers afterwards.
```js
var source1 = Rx.Observable.range(1, 3);
var source2 = Rx.Observable.range(1, 3);
source1.concat(source2)
.subscribe(function (x) { console.log(x); });
// => 1
// => 2
// => 3
// => 1
// => 2
// => 3
```
Notice that the resultant sequence is 1,2,3,1,2,3. This is because when you use the [`concat`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypeconcatargs) operator, the 2nd sequence (source2) will not be active until after the 1st sequence (source1) has finished pushing all its values. It is only after source1 has completed, then source2 will start to push values to the resultant sequence. The subscriber will then get all the values from the resultant sequence.
Compare this with the [`merge`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypemergemaxconcurrent--other) operator. If you run the following sample code, you will get 1,1,2,2,3,3. This is because the two sequences are active at the same time and values are pushed out as they occur in the sources. The resultant sequence only completes when the last source sequence has finished pushing values.
```js
var source1 = Rx.Observable.range(1, 3);
var source2 = Rx.Observable.range(1, 3);
source1.merge(source2)
.subscribe(function (x) { console.log(x); });
// => 1
// => 1
// => 2
// => 2
// => 3
// => 3
```
Another comparison can be done with the [`catch`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypecatchsecond--handler) operator. In this case, if source1 completes without any error, then source2 will not start. Therefore, if you run the following sample code, you will get 1,2,3 only since source2 (which produces 4,5,6) is ignored.
```js
var source1 = Rx.Observable.range(1, 3);
var source2 = Rx.Observable.range(4, 3);
source1.catch(source2)
.subscribe(function (x) { console.log(x); });
// => 1
// => 2
// => 3
```
Finally, let’s look at [`onErrorResumeNext`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypeonerrorresumenextsecond). This operator will move on to source2 even if source1 cannot be completed due to an error. In the following example, even though source1 represents a sequence that terminates with an exception by using the [`throw`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablethrowexception-scheduler) operator, the subscriber will receive values (1,2,3) published by source2. Therefore, if you expect either source sequence to produce any error, it is a safer bet to use [`onErrorResumeNext`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypeonerrorresumenextsecond) to guarantee that the subscriber will still receive some values.
```js
var source1 = Rx.Observable.throw(new Error('An error has occurred.'));
var source2 = Rx.Observable.range(1, 3);
source1.onErrorResumeNext(source2)
.subscribe(function (x) { console.log(x); });
// => 1
// => 2
// => 3
```
## Projection ##
The [`select`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypeselectselector-thisarg) or [`map`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypemapselector-thisarg) operator can translate each element of an observable sequence into another form.
In the following example, we project a sequence of strings into an a series of integers representing the length.
```js
var array = ['Reactive', 'Extensions', 'RxJS'];
var seqString = Rx.Observable.from(array);
var seqNum = seqString.map(function (x) { return x.length; });
seqNum
.subscribe(function (x) { console.log(x); });
// => 8
// => 10
// => 4
```
In the following sample, which is an extension of the event conversion example we saw in the [Bridging with Existing Events](events.md) topic, we use the `select` or `map` operator to project the event arguments to a point of x and y. In this way, we are transforming a mouse move event sequence into a data type that can be parsed and manipulated further, as can be seen in the next "Filtering" section.
```js
var move = Rx.Observable.fromEvent(document, 'mousemove');
var points = move.map(function (e) {
return { x: e.clientX, y: e.clientY };
});
points.subscribe(
function (pos) {
console.log('Mouse at point ' + pos.x + ', ' + pos.y);
});
```
Finally, let’s look at the [`selectMany`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypeselectmanyselector-resultselector) or [`flatMap`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypeflatmapselector-resultselector) operator. The `selectMany` or `flatMap` operator has many overloads, one of which takes a selector function argument. This selector function is invoked on every value pushed out by the source observable. For each of these values, the selector projects it into a mini observable sequence. At the end, the `selectMany` or `flatMap` operator flattens all of these mini sequences into a single resultant sequence, which is then pushed to the subscriber.
The observable returned from `selectMany` or `flatMap` publishes `onCompleted` after the source sequence and all mini observable sequences produced by the selector have completed. It fires `onError` when an error has occurred in the source stream, when an exception was thrown by the selector function, or when an error occurred in any of the mini observable sequences.
In the following example, we first create a source sequence which produces an integer every 5 seconds, and decide to just take the first 2 values produced (by using the `take` operator). We then use `selectMany` or `flatMap` to project each of these integers using another sequence of {100, 101, 102}. By doing so, two mini observable sequences are produced, {100, 101, 102} and {100, 101, 102}. These are finally flattened into a single stream of integers of {100, 101, 102, 100, 101, 102} and pushed to the observer.
```js
var source1 = Rx.Observable.interval(5000).take(2);
var proj = Rx.Observable.range(100, 3);
var resultSeq = source1.flatMap(proj);
var subscription = resultSeq.subscribe(
function (x) { console.log('onNext: ' + x); },
function (e) { console.log('onError: ' + e.message); },
function () { console.log('onCompleted'); });
// => onNext: 100
// => onNext: 101
// => onNext: 102
// => onNext: 100
// => onNext: 101
// => onNext: 102
// => onCompleted
```
## Filtering ##
In the following example, we use the [`generate`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablegenerateinitialstate-condition-iterate-resultselector-scheduler) operator to create a simple observable sequence of numbers. The `generate` operator has several versions including with relative and absolute time scheduling. In our example, it takes an initial state (0 in our example), a conditional function to terminate (fewer than 10 times), an iterator (+1), a result selector (a square function of the current value), and prints out only those smaller than 5 using the [`filter`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypefilterpredicate-thisarg) or [`where`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypewherepredicate-thisarg) operators.
```js
var seq = Rx.Observable.generate(
0,
function (i) { return i < 10; },
function (i) { return i + 1; },
function (i) { return i * i; });
var source = seq.filter(function (n) { return n < 5; });
var subscription = source.subscribe(
function (x) { console.log('onNext: ' + x); },
function (e) { console.log('onError: ' + e.message); },
function () { console.log('onCompleted'); });
// => onNext: 0
// => onNext: 1
// => onNext: 4
// => onCompleted
```
The following example is an extension of the projection example you have seen earlier in this topic. In that sample, we have used the `select` or `map` operator to project the event arguments into a point with x and y. In the following example, we use the `filter` or `where` and `select` or `map` operator to pick only those mouse movement that we are interested. In this case, we filter the mouse moves to those over the first bisector (where the x and y coordinates are equal).
```js
var move = Rx.Observable.fromEvent(document, 'mousemove');
var points = move.map(function (e) {
return { x: e.clientX, y: e.clientY };
});
var overfirstbisector = points.filter(function (pos) {
return pos.x === pos.y;
});
var movesub = overfirstbisector.subscribe(function (pos) { console.log('mouse at ' + pos.x + ', ' + pos.y); });
```
## Time-based Operation ##
You can use the Buffer operators to perform time-based operations.
Buffering an observable sequence means that an observable sequence’s values are put into a buffer based on either a specified timespan or by a count threshold. This is especially helpful in situations when you expect a tremendous amount of data to be pushed out by the sequence, and the subscriber does not have the resource to process these values. By buffering the results based on time or count, and only returning a sequence of values when the criteria is exceeded (or when the source sequence has completed), the subscriber can process OnNext calls at its own pace.
In the following example, we first create a simple sequence of integers for every second. We then use the `bufferWithCount` operator and specify that each buffer will hold 5 items from the sequence. The `onNext` is called when the buffer is full. We then tally the sum of the buffer using calling `Array.reduce`. The buffer is automatically flushed and another cycle begins. The printout will be 10, 35, 60… in which 10=0+1+2+3+4, 35=5+6+7+8+9, and so on.
```js
var seq = Rx.Observable.interval(1000);
var bufSeq = seq.bufferWithCount(5);
bufSeq
.map(function (arr) { return arr.reduce(function (acc, x) { return acc + x; }, 0); })
.subscribe(function (sum) { console.log(sum); });
// => 10
// => 35
// => 60
...
```
We can also create a buffer with a specified time span in milliseconds. In the following example, the buffer will hold items that have accumulated for 3 seconds. The printout will be 3, 12, 21… in which 3=0+1+2, 12=3+4+5, and so on.
```js
var seq = Rx.Observable.interval(1000);
var bufSeq = seq.bufferWithTime(3000);
bufSeq
.map(function (arr) { return arr.reduce(function (acc, x) { return acc + x; }, 0); })
.subscribe(function (sum) { console.log(sum); });
```
Note that if you are using any of the `buffer*` or `window*` operators, you have to make sure that the sequence is not empty before filtering on it.
## Operators by Categories ##
The [Operators by Categories](categories.md) topic lists of all major operators implemented by the `Observable` type by their categories; specifically: creation, conversion, combine, functional, mathematical, time, exceptions, miscellaneous, selection and primitives.
## See Also ##
*Reference*
- [Observable](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
*Concepts*
- [Operators by Categories](categories.md)
================================================
FILE: doc/gettingstarted/schedulers.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Using Schedulers #
A scheduler controls when a subscription starts and when notifications are published. It consists of three components. It is first a data structure. When you schedule for tasks to be completed, they are put into the scheduler for queueing based on priority or other criteria. It also offers an execution context which denotes where the task is executed (e.g. immediately, in the current thread, or in another callback mechanism such as `setTimeout` or `process.nextTick`). Lastly, it has a clock which provides a notion of time for itself (by accessing the `now` method of a scheduler). Tasks being scheduled on a particular scheduler will adhere to the time denoted by that clock only.
Schedulers also introduce the notion of virtual time (denoted by the [`VirtualTimeScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/virtualtimescheduler.md) type), which does not correlate with real time that is used in our daily life. For example, a sequence that is specified to take 100 years to complete can be scheduled to complete in virtual time in a mere 5 minutes. This will be covered in the [Testing and Debugging Observable Sequences](testing.md) topic.
## Scheduler Types ##
The various Scheduler types provided by Rx all implement the `Scheduler` methods. Each of these can be created and returned by using static properties of the `Scheduler` object. The `ImmediateScheduler` (by accessing the static [`immediate`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/scheduler.md#rxschedulerimmediate) property) will start the specified action immediately. The `CurrentThreadScheduler` (by accessing the static [`currentThread`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/scheduler.md#rxschedulercurrentthread) property) will schedule actions to be performed on the thread that makes the original call. The action is not executed immediately, but is placed in a queue and only executed after the current action is complete. The `DefaultScheduler` (by accessing the static [`default`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/scheduler.md#rxschedulerdefault) property) will schedule actions to be performed on a asynchronous callback, which is optimized for the particular runtime, such as `setImmediate` or `process.nextTick` on Node.js or in the browser with a fallback to `setTimeout`.
## Using Schedulers ##
You may have already used schedulers in your Rx code without explicitly stating the type of schedulers to be used. This is because all Observable operators that deal with concurrency have optional schedulers. If you do not provide the scheduler, RxJS will pick a default scheduler by using the principle of least concurrency. This means that the scheduler which introduces the least amount of concurrency that satisfies the needs of the operator is chosen. For example, for operators returning an observable with a finite and small number of messages, RxJS calls `immediate`. For operators returning a potentially large or infinite number of messages, `currentThread` is called. For operators which use timers, `default` is used.
Because RxJS uses the least concurrency scheduler, you can pick a different scheduler if you want to introduce concurrency for performance purpose. To specify a particular scheduler, you can use those operator methods that take a scheduler, e.g., `return(42, Rx.Scheduler.default)`.
In the following example, the source observable sequence is producing values at a frantic pace. The default scheduler of the generate operator would place onNext messages on the `currentThread`.
```js
var obs = Rx.Observable.generate(
0,
function () { return true; },
function (x) { return x + 1; },
function (x) { return x; });
```
This will queue up on the observer quickly. We can improve this code by using the observeOn operator, which allows you to specify the context that you want to use to send pushed notifications (onNext) to observers. By default, the [`observeOn`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/observeon.md) operator ensures that `onNext` will be called as many times as possible on the current thread. You can use its overloads and redirect the `onNext` outputs to a different context. In addition, you can use the [`subscribeOn`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/subscribeon.md) operator to return a proxy observable that delegates actions to a specific scheduler. For example, for a UI-intensive application, you can delegate all background operations to be performed on a scheduler running in the background by using `subscribeOn` and passing to it the `DefaultScheduler`.
The following example will schedule any onNext notifications on the current Dispatcher, so that any value pushed out is sent on the UI thread. This is especially beneficial to Silverlight developers who use RxJS.
```js
Rx.Observable.generate(
0,
function () { return true; },
function (x) { return x + 1; },
function (x) { return x; }
)
.observeOn(Rx.Scheduler.default)
.subscribe(...);
```
Instead of using the `observeOn` operator to change the execution context on which the observable sequence produces messages, we can create concurrency in the right place to begin with. As operators parameterize introduction of concurrency by providing a scheduler argument overload, passing the right scheduler will lead to fewer places where the ObserveOn operator has to be used. For example, we can unblock the observer and subscribe to the UI thread directly by changing the scheduler used by the source, as in the following example. In this code, by using the `generate` method passing a scheduler, and providing the `Rx.Scheduler.default` instance, all values pushed out from this observable sequence will originate via an asynchronous callback.
```js
Rx.Observable.generate(
0,
function () { return true; },
function (x) { return x + 1; },
function (x) { return x; },
Rx.Scheduler.default)
.subscribe(...);
```
You should also note that by using the `observeOn` operator, an action is scheduled for each message that comes through the original observable sequence. This potentially changes timing information as well as puts additional stress on the system. If you have a query that composes various observable sequences running on many different execution contexts, and you are doing filtering in the query, it is best to place `observeOn` later in the query. This is because a query will potentially filter out a lot of messages, and placing the `observeOn` operator earlier in the query would do extra work on messages that would be filtered out anyway. Calling the `observeOn` operator at the end of the query will create the least performance impact.
Another advantage of specifying a scheduler type explicitly is that you can introduce concurrency for performance purpose, as illustrated by the following code.
```js
seq.groupBy(...)
.map(function (x) { return x.observeOn(Rx.Scheduler.default); })
.map(function (x) { return expensive(x); }) // perform operations that are expensive on resources
```
## When to Use Which Scheduler ##
To make things a little easier when you are creating your own operators, or using the standard built-in ones, which scheduler you should use. The following table lays out each scenario with the suggested scheduler.
## See Also
*Reference*
- [Testing and Debugging Observable Sequences](testing.md)
================================================
FILE: doc/gettingstarted/subjects.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Using Subjects #
The [`Subject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md) class inherits both [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md) and [`Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md), in the sense that it is both an observer and an observable. You can use a subject to subscribe all the observers, and then subscribe the subject to a backend data source. In this way, the subject can act as a proxy for a group of subscribers and a source. You can use subjects to implement a custom observable with caching, buffering and time shifting. In addition, you can use subjects to broadcast data to multiple subscribers.
By default, subjects do not perform any synchronization across threads. They do not take a scheduler but rather assume that all serialization and grammatical correctness are handled by the caller of the subject. A subject simply broadcasts to all subscribed observers in the thread-safe list of subscribers. Doing so has the advantage of reducing overhead and improving performance.
## Using Subjects ##
In the following example, we create a subject, subscribe to that subject and then use the same subject to publish values to the observer. By doing so, we combine the publication and subscription into the same source.
In addition to taking an `Observer`, the [`subscribe`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypesubscribeobserver--onnext-onerror-oncompleted) method can also take a function for onNext, which means that the action will be executed every time an item is published. In our sample, whenever onNext is invoked, the item will be written to the console.
```js
var subject = new Rx.Subject();
var subscription = subject.subscribe(
function (x) { console.log('onNext: ' + x); },
function (e) { console.log('onError: ' + e.message); },
function () { console.log('onCompleted'); });
subject.onNext(1);
// => onNext: 1
subject.onNext(2);
// => onNext: 2
subject.onCompleted();
// => onCompleted
subscription.dispose();
```
The following example illustrates the proxy and broadcast nature of a `Subject`. We first create a source sequence which produces an integer every 1 second. We then create a `Subject`, and pass it as an observer to the source so that it will receive all the values pushed out by this source sequence. After that, we create another two subscriptions, this time with the subject as the source. The `subSubject1` and `subSubject2` subscriptions will then receive any value passed down (from the source) by the `Subject`.
```js
// Every second
var source = Rx.Observable.interval(1000);
var subject = new Rx.Subject();
var subSource = source.subscribe(subject);
var subSubject1 = subject.subscribe(
function (x) { console.log('Value published to observer #1: ' + x); },
function (e) { console.log('onError: ' + e.message); },
function () { console.log('onCompleted'); });
var subSubject2 = subject.subscribe(
function (x) { console.log('Value published to observer #2: ' + x); },
function (e) { console.log('onError: ' + e.message); },
function () { console.log('onCompleted'); });
setTimeout(function () {
// Clean up
subject.onCompleted();
subSubject1.dispose();
subSubject2.dispose();
}, 5000);
// => Value published to observer #1: 0
// => Value published to observer #2: 0
// => Value published to observer #1: 1
// => Value published to observer #2: 1
// => Value published to observer #1: 2
// => Value published to observer #2: 2
// => Value published to observer #1: 3
// => Value published to observer #2: 3
// => onCompleted
// => onCompleted
```
## Different types of Subjects ##
The `Subject` object in the RxJS library is a basic implementation, but you can create your own using the [`Subject.create`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md#rxsubjectcreateobserver-observable) method. There are other implementations of Subjects that offer different functionalities. All of these types store some (or all of) values pushed to them via onNext, and broadcast it back to its observers. In this way, they convert a Cold Observable into a Hot one. This means that if you Subscribe to any of these more than once (i.e. subscribe -> unsubscribe -> subscribe again), you will see at least one of the same value again. For more information on hot and cold observables, see the last section of the [Creating and Subscribing to Simple Observable Sequences](creating.md) topic.
[`ReplaySubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/replaysubject.md) stores all the values that it has published. Therefore, when you subscribe to it, you automatically receive an entire history of values that it has published, even though your subscription might have come in after certain values have been pushed out. [`BehaviorSubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md) is similar to `ReplaySubject`, except that it only stored the last value it published. `BehaviourSubject` also requires a default value upon initialization. This value is sent to observers when no other value has been received by the subject yet. This means that all subscribers will receive a value instantly on `subscribe`, unless the `Subject` has already completed. [`AsyncSubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/asyncsubject.md) is similar to the Replay and Behavior subjects, however it will only store the last value, and only publish it when the sequence is completed. You can use the `AsyncSubject` type for situations when the source observable is hot and might complete before any observer can subscribe to it. In this case, `AsyncSubject` can still provide the last value and publish it to any future subscribers.
================================================
FILE: doc/gettingstarted/testing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Testing your Rx application #
Let's face it, testing asynchronous code is a pain. In JavaScript, with so many asynchronous things to coordinate, testing can be tricky. We think you'll find the Reactive Extensions for JavaScript makes it easier.
If you have an observable sequence that publishes values over an extended period of time, testing it in real time can be a stretch. The RxJS library provides the [`TestScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md) type to assist testing this kind of time-dependent code without actually waiting for time to pass. The `TestScheduler` inherits [`VirtualScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/virtualtimescheduler.md) and allows you to create, publish and subscribe to sequences in emulated time. For example, you can compact a publication which takes 5 days to complete into a 2 minute run, while maintaining the correct scale. You can also take a sequence which actually has happened in the past (e.g., a sequence of stock ticks for a previous year) and compute or subscribe to it as if it is pushing out new values in real time.
The factory methods [`startWithTiming`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md#rxtestschedulerprototypestartwithtimingcreate-created-subscribed-disposed), [`startWithCreate`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md#rxtestschedulerprototypestartwithcreatecreate) and [`startWithDispose`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md#rxtestschedulerprototypestartwithdisposecreate-disposed) executes all scheduled tasks until the queue is empty, or you can specify a time to so that queued-up tasks are only executed to the specified time.
The following example creates a hot observable sequence with specified `onNext` notifications. It then starts the test scheduler and specifies when to subscribe to and dispose of the hot observable sequence. The Start method returns an instance of an `Observer`, which contains a `messages` property that records all notifications in a list.
After the sequence has completed, we can use methods such as `collectionAssert.assertEqual` to compare the `messages` property, together with a list of expected values to see if both are identical (with the same number of items, and items are equal and in the same order). By doing so, we can confirm that we have indeed received the notifications that we expect. In our example, since we only start subscribing at 150, we will miss out the value 'abc'. However, when we compare the values we have received so far at 400, we notice that we have in fact received all the published values after we subscribed to the sequence. And we also verify that the OnCompleted notification was fired at the right time at 500. In addition, subscription information is also captured by the `Observable` type returned by the [`createHotObservable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md#rxtestschedulerprototypecreatehotobservableargs) method.
In the same way, you can use that same defined method such as our `collectionAssert.assertEqual` below to confirm that subscriptions indeed happened at expected times. It is easy to wrap this for your favorite unit testing framework whether it is QUnit, Mocha, Jasmine, etc. In this example, we'll write a quick wrapper for QUnit.
```js
function createMessage(expected, actual) {
return 'Expected: [' + expected.toString() + ']\r\nActual: [' + actual.toString() + ']';
}
// Using QUnit testing for assertions
var collectionAssert = {
assertEqual: function (actual, expected) {
var comparer = Rx.internals.isEqual, isOk = true;
if (expected.length !== actual.length) {
ok(false, 'Not equal length. Expected: ' + expected.length + ' Actual: ' + actual.length);
return;
}
for(var i = 0, len = expected.length; i < len; i++) {
isOk = comparer(expected[i], actual[i]);
if (!isOk) {
break;
}
}
ok(isOk, createMessage(expected, actual));
}
};
var onNext = Rx.ReactiveTest.onNext,
onCompleted = Rx.ReactiveTest.onCompleted,
subscribe = Rx.ReactiveTest.subscribe;
test('buffer should join strings', function () {
var scheduler = new Rx.TestScheduler();
var input = scheduler.createHotObservable(
onNext(100, 'abc'),
onNext(200, 'def'),
onNext(250, 'ghi'),
onNext(300, 'pqr'),
onNext(450, 'xyz'),
onCompleted(500)
);
var results = scheduler.startScheduler(
function () {
return input.buffer(function () {
return input.debounce(100, scheduler);
})
.map(function (b) {
return b.join(',');
});
},
{
created: 50,
subscribed: 150,
disposed: 600
}
);
collectionAssert.assertEqual(results.messages, [
onNext(400, 'def,ghi,pqr'),
onNext(500, 'xyz'),
onCompleted(500)
]);
collectionAssert.assertEqual(input.subscriptions, [
subscribe(150, 500),
subscribe(150, 400),
subscribe(400, 500)
]);
});
```
## Debugging your Rx application ##
You can use the [`do`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypedoobserver--onnext-onerror-oncompleted) operator to debug your Rx application. The `do` operator allows you to specify various actions to be taken for each item of observable sequence (e.g., print or log the item, etc.). This is especially helpful when you are chaining many operators and you want to know what values are produced at each level.
In the following example, we are going to reuse the Buffer example which generates integers every second, while putting them into buffers that can hold 5 items each. In our original example in the [Querying Observable Sequences](querying.md) topic, we subscribe only to the final `Observable` sequence when the buffer is full (and before it is emptied). In this example, however, we will use the `do` operator to print out the values when they are being pushed out by the original sequence (an integer every second). When the buffer is full, we use the `do` operator to print the status, before handing over all this as the final sequence for the observer to subscribe.
```js
var seq1 = Rx.Observable.interval(1000)
.do(function (x) { console.log(x); })
.bufferWithCount(5)
.do(function (x) { console.log('buffer is full'); })
.subscribe(function (x) { console.log('Sum of the buffer is ' + x.reduce(function (acc, x) { return acc + x; }, 0)); });
// => 0
// => 1
// => 2
// => 3
// => 4
// => buffer is full
// => Sum of the buffer is 10
// ...
```
As you can see from this sample, a subscription is on the recipient end of a series of chained observable sequences. At first, we create an observable sequence of integers separate by a second using the Interval operator. Then, we put 5 items into a buffer using the Buffer operator, and send them out as another sequence only when the buffer is full. Lastly, this is handed over to the Subscribe operator. Data propagate down all these intermediate sequences until they are pushed to the observer. In the same way, subscriptions are propagated in the reverse direction to the source sequence. By inserting the `do` operator in the middle of such propagations, you can "spy" on such data flow just like you use console.log perform debugging.
You can also use the [`timestamp`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypetimestampscheduler) operator to verify the time when an item is pushed out by an observable sequence. This can help you troubleshoot time-based operations to ensure accuracy. Recall the following example from the [Creating and Subscribing to Simple Observable Sequences](creating.md) topic, in which we chain the `timestamp` operator to the query so that each value pushed out by the source sequence will be appended by the time when it is published. By doing so, when we subscribe to this source sequence, we can receive both its value and timestamp.
```js
console.log('Current time: ' + Date.now());
var source = Rx.Observable.timer(5000, 1000)
.timestamp();
var subscription = source.subscribe(function (x) {
console.log(x.value + ': ' + x.timestamp);
});
/* Output will look similar to this */
// => Current time: 1382646947400
// => 0: 1382646952400
// => 1: 1382646953400
// => 2: 1382646954400
// => 3: 1382646955400
// => 4: 1382646956400
// => 5: 1382646957400
// => 6: 1382646958400
```
By using the `timestamp` operator, we have verified that the first item is indeed pushed out 5 seconds after the sequence, and each item is published 1 second later.
You can remove any `do` and `map` or `select` calls after you finish debugging.
## Long Stack Traces Support
When dealing with large RxJS applications, debugging and finding where the error occurred can be a difficult operation. As you chain more and more operators together, the longer the stack trace gets, and the harder it is to find out where things went wrong. Inspiration for this feature came from the [Q library](https://github.com/kriskowal/q) from [@kriskowal](https://github.com/kriskowal) which helped us get started.
RxJS comes with optional support for "long stack traces" where the stack property of Error from onError calls is rewritten to be traced along asynchronous jumps instead of stopping at the most recent one. As an example:
```js
var Rx = require('rx');
var source = Rx.Observable.range(0, 100)
.timestamp()
.map(function (x) {
if (x.value > 98) throw new Error();
return x;
});
source.subscribeOnError(
function (err) {
console.log(err.stack);
});
```
The error stack easily becomes unreadable and hard to find where the error actually occurred:
```bash
$ node example.js
Error
at C:\GitHub\example.js:6:29
at AnonymousObserver._onNext (C:\GitHub\rxjs\dist\rx.all.js:4013:31)
at AnonymousObserver.Rx.AnonymousObserver.AnonymousObserver.next (C:\GitHub\rxjs\dist\rx.all.js:1863:12)
at AnonymousObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AutoDetachObserverPrototype.next (C:\GitHub\rxjs\dist\rx.all.js:9226:23)
at AutoDetachObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AnonymousObserver._onNext (C:\GitHub\rxjs\dist\rx.all.js:4018:18)
at AnonymousObserver.Rx.AnonymousObserver.AnonymousObserver.next (C:\GitHub\rxjs\dist\rx.all.js:1863:12)
at AnonymousObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AutoDetachObserverPrototype.next (C:\GitHub\rxjs\dist\rx.all.js:9226:23)
```
Instead, we can turn on this feature by setting the following flag:
```js
Rx.config.longStackSupport = true;
```
When running the same example again with the flag set at the top, our stack trace looks much nicer and indicates exactly where the error occurred:
```bash
$ node example.js
Error
at C:\GitHub\example.js:6:29
From previous event:
at Object. (C:\GitHub\example.js:3:28)
From previous event:
at Object. (C:\GitHub\example.js:4:4)
From previous event:
at Object. (C:\GitHub\example.js:5:4)
```
Now, it is more clear that the error did occur exactly at line 6 with throwing an error and only shows the user code in this point. This is very helpful for debugging, as otherwise you end up getting only the first line, plus a bunch of RxJS internals, with no sign of where the operation started.
This feature does come with a serious performance and memory overhead, however, If you're working with lots of RxJS code, or trying to scale a server to many users, you should probably keep it off. In development, this is perfectly fine for finding those pesky errors!
In a future release, we may also release support for a node.js environment variable so that you can set it and unset it fairly easily.
## See Also ##
**Concepts**
- [Creating and Subscribing to Simple Observable Sequences](creating.md)
- [Querying Observable Sequences](querying.md)
- [Using Schedulers](schedulers.md)
================================================
FILE: doc/gettingstarted/transducers.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Transducers with Observable Sequences #
Much like Language Integrated Query (LINQ), Transducers are composable algorithmic transformations. They, like LINQ, are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates. There are two major libraries currently out there, Cognitect's [`transducer-js`](https://github.com/cognitect-labs/transducers-js) and James Long's [`transducers.js`](https://github.com/jlongster/transducers.js) which are both great for getting high performance over large amounts of data. Because it is collection type neutral, it is a perfect fit for RxJS to do transformations over large collections.
The word `transduce` is just a combination of `transform` and `reduce`. The reduce function is the base transformation; any other transformation can be expressed in terms of it (`map`, `filter`, etc).
```js
var arr = [1, 2, 3, 4];
arr.reduce(
function(result, x) { return result.concat(x + 1); }, []);
// => [ 2, 3, 4, 5 ]
```
Using transducers, we can model the following behavior while breaking apart the map aspect of adding 1 to the concat operation, adding the seed and then the "collection" to transduce.
```js
var arr = [1, 2, 3, 4];
function increment(x) { return x + 1; }
function concatItem(acc, x) { return acc.concat(x); }
transduce(map(increment), concatItem, [], arr);
// => [ 2, 3, 4, 5 ]
```
Using Cognitect's [`transducers-js`](https://github.com/cognitect-labs/transducers-js) library, we can easily accomplish what we had above.
```js
var t = transducers;
var arr = [1, 2, 3, 4];
function increment(x) { return x + 1; }
into([], t.comp(t.map(increment)), arr);
// => [ 2, 3, 4, 5 ]
```
We can go a step further and add filtering as well to get only even values.
```js
var t = transducers;
var arr = [1, 2, 3, 4];
function increment(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }
into([], t.comp(t.map(increment), t.filter(isEven)), arr);
// => [ 2, 4 ]
```
Since it works so well using Arrays, there's no reason why it cannot work for Observable sequences as well. To that end, we have introduced the [`transduce`](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators/transduce.md) method which acts exactly like it does for Arrays, but for Observable sequences. Once again, let's go over the above example, this time using an Observable sequence.
```js
var t = transducers;
var source = Rx.Observable.range(1, 4);
function increment(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }
var transduced = source.transduce(t.comp(t.map(increment), t.filter(isEven)));
transduced.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function () { console.log('Completed'); });
// => Next: 2
// => Next: 4
// => Completed
```
Note that this above example also works the same with `transducers.js` as well with little to no modification. This example will in fact work faster than the traditional LINQ style (as of now) which most use currently.
```js
var source = Rx.Observable.range(1, 4);
function increment(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }
var transduced = source.map(increment).filter(isEven);
transduced.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function () { console.log('Completed'); });
// => Next: 2
// => Next: 4
// => Completed
```
This opens up a wide new set of possibilities making RxJS even faster over large collections with no intermediate Observable sequences.
================================================
FILE: doc/gettingstarted/what.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# What are the Reactive Extensions for JavaScript (RxJS)? #
The Reactive Extensions for JavaScript (RxJS) is a library for composing asynchronous and event-based programs using observable sequences and [LINQ-style query operators](http://en.wikipedia.org/wiki/LINQ). Using RxJS, developers *__represent__* asynchronous data streams with [Observables](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md), *__query__* asynchronous data streams using [LINQ operators](http://msdn.microsoft.com/en-us/library/hh242983.aspx), and *__parameterize__* the concurrency in the asynchronous data streams using [Schedulers](http://msdn.microsoft.com/en-us/library/hh242963.aspx). Simply put, Rx = Observables + LINQ + Schedulers.
Whether you are authoring a web-based application or server-side applications with [Node.js](http://nodejs.org), you have to deal with asynchronous and event-based programming constantly. Web applications and Node.js applications have I/O operations and computationally expensive tasks that might take a long time to complete and potentially block the main thread. Furthermore, handling exceptions, cancellation, and synchronization is difficult and error-prone.
Using RxJS, you can represent multiple asynchronous data streams (that come from diverse sources, e.g., stock quote, tweets, computer events, web service requests, etc.), and subscribe to the event stream using the `Observer` object. The `Observable` object notifies the subscribed `Observer` object whenever an event occurs.
Because observable sequences are data streams, you can query them using standard query operators implemented by the Observable extension methods. Thus you can filter, project, aggregate, compose and perform time-based operations on multiple events easily by using these standard query operators. In addition, there are a number of other reactive stream specific operators that allow powerful queries to be written. Cancellation, exceptions, and synchronization are also handled gracefully by using the extension methods provided by Rx.
RxJS complements and interoperates smoothly with both synchronous data streams such as Arrays, Sets and Maps and single-value asynchronous computations such as Promises as the following diagram shows:
Single return value
Mutiple return values
Pull/Synchronous/Interactive
Object
Iterables (Array | Set | Map | Object)
Push/Asynchronous/Reactive
Promise
Observable
## Pushing vs. Pulling Data ##
In interactive programming, the application actively polls a data source for more information by retrieving data from a sequence that represents the source. Such behavior is represented by the iterator pattern of JavaScript Arrays, Objects, Sets, Maps, etc. In interactive programming, one must get the next item by either getting an item by an index in an Array, or through [ES6 iterators](http://wiki.ecmascript.org/doku.php?id=harmony:iterators).
The application is active in the data retrieval process: it decides about the pace of the retrieval by calling `next` at its own convenience. This enumeration pattern is synchronous, which means your application might be blocked while polling the data source. Such pulling pattern is similar to visiting your library and checking out a book. After you are done with the book, you pay another visit to check out another one.
On the other hand, in reactive programming, the application is offered more information by subscribing to a data stream (called observable sequence in RxJS), and any update is handed to it from the source. The application is passive in the data retrieval process: apart from subscribing to the observable source, it does not actively poll the source, but merely react to the data being pushed to it. When the event has completed, the source will send a notice to the subscriber. In this way, your application will not be blocked by waiting for the source to update.
This is the push pattern employed by Reactive Extensions for JavaScript. This is similar to joining a book club in which you register your interest in a particular genre, and books that match your interest are automatically sent to you as they are published. You do not need to stand in a line to acquire something that you want. Employing a push pattern is especially helpful in heavy UI environment in which the UI thread cannot be blocked while the application is waiting for some events, which is essential in JavaScript environments which has its own set of asynchronous requirements. In summary, by using RxJS, you can make your application more responsive.
The push model implemented by Rx is represented by the observable pattern of `Observable`/`Observer`. The `Observable` will notify all the observers automatically of any state changes. To register an interest through a subscription, you use the `subscribe` method of `Observable`, which takes on an `Observer` and returns a `Disposable` object. This gives you the ability to track your subscription and be able to dispose the subscription. You can essentially treat the observable sequence (such as a sequence of mouseover events) as if it were a normal collection. RxJS’s built-in query implementation over observable sequences allows developers to compose complex event processing queries over push-based sequences such as events, callbacks, Promises, HTML5 Geolocation APIs, and much much more.. For more information on these two interfaces, see [Exploring The Major Concepts in RxJS](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/exploring.md).
================================================
FILE: doc/gettingstarted/which-instance.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Which Operator to Use? - Instance Operators #
Use this page to find the instance operator implemented by the [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md) type that fits your needs:
## See Also ##
*Reference*
- [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
*Concepts*
- [Querying Observable Sequences](querying.md)
- [Operators By Category](categories.md)
================================================
FILE: doc/gettingstarted/which-static.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Which Operator to Use? - Creation Operators #
Use this page to find the creation operator implemented by the [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md) type that fits your needs:
## See Also ##
*Reference*
- [`Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
*Concepts*
- [Querying Observable Sequences](querying.md)
- [Operators By Category](categories.md)
================================================
FILE: doc/howdoi/angular.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# How do I integrate Angular.js with RxJS? #
[AngularJS](http://angularjs.org/) is a popular MV* framework for JavaScript which covers things such as data binding, controllers as well as things such as dependency injection. The Reactive Extensions for JavaScript plays well with this framework, and in fact has a dedicated library for interop called [rx.angular.js](https://github.com/Reactive-Extensions/rx.angular.js). However, if you don't wish to use that, here are some simple ways you can integrate the two together.
## Integration with Scopes
The [`scope`](http://docs.angularjs.org/api/ng.$rootScope.Scope) is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can watch expressions and propagate events.
Scopes provide the ability to observe change mutations on the scope through the [`$watch`](http://docs.angularjs.org/api/ng.$rootScope.Scope#methods_$watch) method. This is a perfect opportunity to integrate the power of the Reactive Extensions for JavaScript with Angular. Let's look at a typical usage of `$watch`.
```js
// Get the scope from somewhere
var scope = $rootScope;
scope.name = 'Reactive Extensions';
scope.counter = 0;
scope.$watch('name', function(newValue, oldValue) {
scope.counter = scope.counter + 1;
scope.oldValue = oldValue;
scope.newValue = newValue;
});
// Process All the Watchers
scope.$digest();
// See the counter increment
console.log(counter);
// => 1
```
Using the Reactive Extensions for JavaScript, we're able to easily bind to this by wrapping the `$watch` as an observable. To do this, we'll create an observable sequence using `Rx.Observable.create` which gives us an observer to yield to. In this case, we'll capture both the old and new values through our listener function. The `$watch` function returns a function, which when called, ceases the watch expression.
```js
Rx.Observable.$watch = function (scope, watchExpression, objectEquality) {
return Rx.Observable.create(function (observer) {
// Create function to handle old and new Value
function listener (newValue, oldValue) {
observer.onNext({ oldValue: oldValue, newValue: newValue });
}
// Returns function which disconnects the $watch expression
return scope.$watch(watchExpression, listener, objectEquality);
});
};
```
Now that we have this, we're able to now take the above example and now add some RxJS goodness to it.
```js
// Get the scope from somewhere
var scope = $rootScope;
scope.name = 'Reactive Extensions';
scope.isLoading = false;
scope.data = [];
// Watch for name change and throttle it for 1 second and then query a service
Rx.Observable.$watch(scope, 'name')
.throttle(1000)
.map(function (e) {
return e.newValue;
})
.do(function () {
// Set loading and reset data
scope.isLoading = true;
scope.data = [];
})
.flatMapLatest(querySomeService)
.subscribe(function (data) {
// Set the data
scope.isLoading = false;
scope.data = data;
});
```
## Integration with Deferred/Promise Objects
AngularJS ships a promise/deferred implementation based upon [Kris Kowal's Q](https://github.com/kriskowal/q) called the [`$q`](http://docs.angularjs.org/api/ng.$q) service. Promises are quite useful in scenarios with one and done asynchronous operations such as querying a service through the [`$http`](http://docs.angularjs.org/api/ng.$http) service.
```js
$http.get('/someUrl')
.then(successCallback, errCallback);
```
Using the Reactive Extensions for JavaScript, we can also integrate using the `Rx.Observable.fromPromise` bridge available in RxJS version 2.2+. We simply
```js
// Query data
var observable = Rx.Observable.fromPromise(
$http({
method: 'GET',
url: 'someurl',
params: { searchString: $scope.searchString }
})
);
// Subscribe to data and update UI
observable.subscribe(
function (data) {
$scope.data = data;
},
function (err) {
$scope.error = err.message;
}
);
```
These are just only the beginnings of what you can do with the Reactive Extensions for JavaScript and AngularJS.
================================================
FILE: doc/howdoi/createcustomoperators.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Creating Your Own Custom Operators
Final Result
```js
```
================================================
FILE: doc/howdoi/eventemitter.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# How do I create a custom event emitter? #
Publish/Subscribe is a common pattern within JavaScript applications. The idea is that you have a publisher that emits events and you have consumers which register their interest in a given event. Typically you may see something like the following where you listen for a 'data' event and then the event emitter publishes data to it.
```js
var emitter = new Emitter();
function logData(data) {
console.log('data: ' + data);
}
emitter.on('data', logData);
emitter.emit('data', 'foo');
// => data: foo
// Destroy handler
emitter.off('data', logData);
```
How might one implement this using the Reactive Extensions for JavaScript? Using an `Rx.Subject` will solve this problem easily. As you may remember, an `Rx.Subject` is both an Observer and Observable, so it handles both publish and subscribe.
```js
var subject = new Rx.Subject();
var subscription = subject.subscribe(function (data) {
console.log('data: ' + data);
});
subject.onNext('foo');
// => data: foo
```
Now that we have a basic understanding of publish and subscribe through `onNext` and `subscribe`, let's put it to work to handle multiple types of events at once. First, we'll create an Emitter class which has three main methods, `emit`, `on` and `off` which allows you to emit an event, listen to an event and stop listening to an event.
```js
var hasOwnProp = {}.hasOwnProperty;
function createName (name) {
return '$' + name;
}
function Emitter() {
this.subjects = {};
}
Emitter.prototype.emit = function (name, data) {
var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
this.subjects[fnName].onNext(data);
};
Emitter.prototype.on = function (name, handler) {
var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
this.subjects[fnName].subscribe(handler);
};
Emitter.prototype.off = function (name, handler) {
var fnName = createName(name);
if (this.subjects[fnName]) {
this.subjects[fnName].dispose();
delete this.subjects[fnName];
}
};
Emitter.prototype.dispose = function () {
var subjects = this.subjects;
for (var prop in subjects) {
if (hasOwnProp.call(subjects, prop)) {
subjects[prop].dispose();
}
}
this.subjects = {};
};
```
Then we can use it much as we did above. As the call to `subscribe` returns a subscription, we might want to hand that back to the user instead of providing an off method. So, we could rewrite the above where we call the `on` method to `listen` and we return a subscription handle to the user to stop listening.
```js
var hasOwnProp = {}.hasOwnProperty;
function createName (name) {
return '$' + name;
}
function Emitter() {
this.subjects = {};
}
Emitter.prototype.emit = function (name, data) {
var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
this.subjects[fnName].onNext(data);
};
Emitter.prototype.listen = function (name, handler) {
var fnName = createName(name);
this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
return this.subjects[fnName].subscribe(handler);
};
Emitter.prototype.dispose = function () {
var subjects = this.subjects;
for (var prop in subjects) {
if (hasOwnProp.call(subjects, prop)) {
subjects[prop].dispose();
}
}
this.subjects = {};
};
```
Now we can use this to rewrite our example such as the following:
```js
var emitter = new Emitter();
var subcription = emitter.listen('data', function (data) {
console.log('data: ' + data);
});
emitter.emit('data', 'foo');
// => data: foo
// Destroy the subscription
subscription.dispose();
```
================================================
FILE: doc/howdoi/jquery.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# How do I work with jQuery and RxJS #
The [jQuery](http://jquery.com) project and RxJS play very well together as libraries. In fact, we supply bindings directly for RxJS to jQuery should you want to wrap animations, events, Ajax calls and more using Observables in [RxJS-jQuery](https://github.com/Reactive-Extensions/RxJS-jQuery). The bindings library provides many handy features for bridging the world to Observables. If you're interested in that library, go ahead and use it.
## Using RxJS with Rx-jQuery ##
Getting started with the bindings is easy. Each method is enumerated on the main page from the jQuery method to its RxJS counterpart.
```html
```
Now we can start using the bindings! For example, we can listen to a `click` event and then by using `flatMap` or `selectMap` we can animate by calling `animateAsObservable`. Finally, we can subscribe to cause the side effect and nothing more.
```js
$( "#go" ).clickAsObservable().flatMap(function () {
return $( "#block" ).animateAsObservable({
width: "70%",
opacity: 0.4,
marginLeft: "0.6in",
fontSize: "3em",
borderWidth: "10px"
}, 1500 );
}).subscribe();
```
## Using RxJS with jQuery ##
Let's start though by assuming you just have RxJS and wanted to get started with jQuery without the bridge library. There is already plenty you can do without even needing a bridge library with the support built in for events and promises.
### Binding to an event ###
Using RxJS with jQuery to bind to an event using plain old RxJS is easy. For example, we could bind to the `mousemove` event from the DOM document easily.
First, we'll reference the files we need.
```html
```
```js
var observable = Rx.Observable.fromEvent(
$(document),
'mousemove');
var subscription = observable.subscribe(function (e) {
$('#results').text(e.clientX + ',' + e.clientY);
});
```
We could go a step further and create our own jQuery plugin which handles events with ease.
```js
/**
* Creates an observable sequence by adding an event listener to the matching jQuery element
*
* @param {String} eventName The event name to attach the observable sequence.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence of events from the specified element and the specified event.
*/
jQuery.fn.toObservable = function (eventName, selector) {
return Rx.Observable.fromEvent(this, eventName, selector);
};
```
Now we could rewrite our above example such as this.
```js
var observable = $(document).toObservable('mousemove');
var subscription = observable.subscribe(function (e) {
$('#results').text(e.clientX + ',' + e.clientY);
});
```
### Using RxJS with Ajax calls ###
Bridging to jQuery Ajax calls using [`$.ajax`](http://api.jquery.com/jQuery.ajax/) is easy as well with the built-in [Promises A+](https://github.com/promises-aplus/promises-spec) support. Since jQuery 1.5, the `$.ajax` method has implemented a promise interface (even if not 100% pure) which allows us to bridge to an observable sequence via the `Rx.Observable.fromPromise` method.
For example, we could query Wikipedia by calling the `$.ajax` method and then calling the [`promise`](http://api.jquery.com/deferred.promise/) method which then exposes the minimum promise interface needed.
```js
function searchWikipedia (term) {
var promise = $.ajax({
url: 'http://en.wikipedia.org/w/api.php',
dataType: 'jsonp',
data: {
action: 'opensearch',
format: 'json',
search: encodeURI(term)
}
}).promise();
return Rx.Observable.fromPromise(promise);
}
```
Once we created the wrapper, we can query the service by getting the text and then using `flatMapLatest` to ensure we have no out of order results.
```js
$('#input').toObservable('keyup')
.map(function (e) { return e.target.value; })
.flatMapLatest(searchWikipedia)
.subscribe(function (data) {
var results = data[1];
$.each(results, function (_, result) {
// Do something with each result
});
});
```
### Using RxJS with Callbacks to Handle Simple Animations ###
RxJS can also be used to bind to simple callbacks, such as the [`.animate()`](http://api.jquery.com/animate/) method. We can use `Rx.Observable.fromCallback` to supply the required arguments with the last argument is to be the callback. In this example, we'll take the animation example from above and use nothing but core RxJS to accomplish the same thing.
You'll note that we need a notion of `this` for the `block.animate` to properly work, so we have two choices, either use `Function.prototype.bind` available in most modern browsers...
```js
var animate = Rx.Observable.fromCallback(block.animate.bind(block));
```
Or we can supply an optional argument which supplies the context to the callback such as the following...
```js
var animate = Rx.Observable.fromCallback(
block.animate,
null, /* default scheduler used */
block /* context */);
```
When viewed in its entirety, it will look like this where we call `flatMap` or `selectMany` to compose together two observable sequences. We then bind to the `animate` function through `Rx.Observable.fromCallback` and then return the observable which results from the function execution. Our `subscribe` does nothing in this case as there is nothing to print or do, and is simply a side effect.
```js
var block = $('#block');
$('#go').toObservable('click').flatMap(function () {
var animate = Rx.Observable.fromCallback(block.animate.bind(block));
return animate({
width: "70%",
opacity: 0.4,
marginLeft: "0.6in",
fontSize: "3em",
borderWidth: "10px"
}, 1500);
}).subscribe();
```
================================================
FILE: doc/howdoi/wrap.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# Wrap an Existing API with RxJS
One question that often comes up is how can I wrap an existing API into an Observable sequence? The answer is fairly simple and not a lot of lines of code to make that happen.
To make this a bit more concrete, let's take a familiar HTML5 API like [Geolocation API](http://dev.w3.org/geo/api/spec-source.html), in particular, the `navigator.geolocation.watchPosition` method.
The typical use of this method might be the following where we would hook up an event handler to listen for success and errors on watching the geolocation by using the `navigator.geolocation.watchPosition` method. When one wishes to terminate listening for geolocation updates, you simply call the `navigator.geolocation.clearWatch` method passing in the watch ID returned from the `watchPosition` method.
```js
function watchPositionChanged(e) {
// Do something with the coordinates
}
function watchPositionError(e) {
// Handle position error
}
var watchId = navigator.geolocation.watchPosition(
watchPositionChanged,
watchPositionError);
var stopWatching = document.querySelector('#stopWatching');
stopWatching.addEventListener('click', stopWatchingClicked, false);
// Clear watching upon click
function stopWatchingClicked(e) {
navigator.geolocation.clearWatch(watchId)
}
```
In order to wrap this, we'll need to use the [`Rx.Observable.create`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservablecreatesubscribe) method. From this, we can yield values to the observer or handle the errors. Let's see how the code might look, creating a watchPosition method which takes geolocation options.
```js
function watchPosition(geolocationOptions) {
return Rx.Observable.create(function (observer) {
var watchId = window.navigator.geolocation.watchPosition(
function successHandler (loc) {
observer.onNext(loc);
},
function errorHandler (err) {
observer.onError(err);
},
geolocationOptions);
return function () {
window.navigator.geolocation.clearWatch(watchId);
};
});
}
```
We need to also be aware of ensuring we're not adding too many watchPosition calls as we compose it together with other observable sequences. To do that, we'll need to utilize the [`publish`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#rxobservableprototypepublishselector) and [`refCount`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md#connectableobservableprototyperefcount) methods from rx.binding.js.
Our final result should look like the following:
```js
function watchPosition(geolocationOptions) {
return Rx.Observable.create(function (observer) {
var watchId = window.navigator.geolocation.watchPosition(
function successHandler (loc) {
observer.onNext(loc);
},
function errorHandler (err) {
observer.onError(err);
},
geolocationOptions);
return function () {
window.navigator.geolocation.clearWatch(watchId);
};
}).publish().refCount();
}
```
And now we can consume the geolocation such as:
```js
var source = watchPosition();
var subscription = source.subscribe(
function (position) {
console.log('Next:' + position.coords.latitude + ',' + position.coords.longitude);
},
function (err) {
var message = '';
switch (err.code) {
case err.PERMISSION_DENIED:
message = 'Permission denied';
break;
case err.POSITION_UNAVAILABLE:
message = 'Position unavailable';
break;
case err.PERMISSION_DENIED_TIMEOUT:
message = 'Position timeout';
break;
}
console.log('Error: ' + message);
},
function () {
console.log('Completed');
});
```
================================================
FILE: doc/libraries/core/rx.core.binding.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Core Binding Module #
The Reactive Extensions for JavaScript has a notion of hot and cold observables. Hot observables fire whether you are listening to them or not, such as mouse movements. Cold observables on the other hand, such as a sequence created from an array will fire the same sequence to all subscribers. The Core Binding module gives you the ability to replay events for hot observables, and to turn cold observables into hot observables. The primary use case is for those who are implementing libraries compatible with RxJS to be able to handle hot and cold observables.
## Details ##
Files:
- [`rx.core.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.binding.js)
NPM Packages:
- [`rx-core-binding`](https://www.npmjs.com/package/rx-core-binding)
NuGet Packages:
- _None_
File Dependencies:
- [`rx.core.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.js)
NuGet Dependencies:
- _None_
## Included Observable Operators ##
### `Observable Instance Methods`
- [`connect`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/connect.md)
- [`publish`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publish.md)
- [`publishLast`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publishlast.md)
- [`publishValue`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publishvalue.md)
- [`refCount`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/refcount.md)
- [`replay`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/replay.md)
- [`share`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md)
- [`shareLast`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharelast.md)
- [`shareReplay`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharereplay.md)
- [`shareValue`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharevalue.md)
- [`singleInstance`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/singleinstance.md)
## Included Classes ##
### Subjects
- [`Rx.AsyncSubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/asyncsubject.md)
- [`Rx.Subject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md)
- [`Rx.BehaviorSubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.mdapi/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.mdapi/subjects/replaysubject.md)
================================================
FILE: doc/libraries/core/rx.core.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Core Module #
The Reactive Extensions for JavaScript's core functionality for conforming to the RxJS contract can be found here. This module contains only the bare essentials including Disposables, Schedulers, Observer and Observable. This is made available with the `rx.core.js` file. The primary use case for this file is for those who want to implement a minimal implementation of RxJS for their own usage.
## Details ##
Files:
- [`rx.core.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.js)
NPM Packages:
- [`rx-core`](https://www.npmjs.com/package/rx-core)
NuGet Packages:
- _None_
## Included Classes ##
### Core Objects
- [`Rx.Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md)
- [`Rx.Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
### `Observable Methods`
- [`create`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md)
### Schedulers
- [`Rx.Scheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/compositedisposable.md)
- [`Rx.Disposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/disposable.md)
- [`Rx.SerialDisposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/singleassignmentdisposable.md)
================================================
FILE: doc/libraries/core/rx.core.testing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Core Testing Module #
The Reactive Extensions for JavaScript has a built-in mechanism for testing all operators which allows for mocking absolute and relative time with ease for use with `rx.core.js` and `rx.core.binding.js`
## Details ##
Files:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.testing.js)
NPM Packages:
- [`rx-core-testing`](https://www.npmjs.com/package/rx-core-testing)
NuGet Packages:
- _None_
File Dependencies:
- [`rx.core.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.js)
NuGet Dependencies:
- _None_
## Included Classes ##
### Core Objects
- [`Rx.Notification`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/notification.md)
### Schedulers
- [`Rx.TestScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md)
- [`Rx.VirtualTimeScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/virtualtimescheduler.md)
### Testing Classes
- [`Rx.ReactiveTest`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/reactivetest.md)
- [`Rx.Recorded`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/recorded.md)
- [`Rx.Subscription`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/subscription.md)
================================================
FILE: doc/libraries/lite/rx.lite.aggregates.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Aggregates Module #
The Reactive Extensions for JavaScript has a number of aggregation operators including those you might already know from the Array#extras and the upcoming ES6 standard such as `reduce`, `find` and `findIndex`. This module is used exclusively for aggregation operations used on finite observable sequences. In addition to the aforementioned operators, there are many useful operators such as `count`, `sum`, `average` and determining whether two sequences are equal via the `sequenceEqual` method. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-aggregates/rx.lite.aggregates.js)
[`rx.lite.aggregates.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-aggregates-compat/rx.lite.aggregates.compat.js)
NPM Packages:
- [`rx-lite-aggregates`](https://www.npmjs.org/package/rx)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
### `Observable Instance Methods`
- [`aggregate`](../../api/core/operators/reduce.md)
- [`all`](../../api/core/operators/every.md)
- [`any`](../../api/core/operators/some.md)
- [`average`](../../api/core/operators/average.md)
- [`includes`](../../api/core/operators/includes.md)
- [`count`](../../api/core/operators/count.md)
- [`elementAt`](../../api/core/operators/elementat.md)
- [`every`](../../api/core/operators/every.md)
- [`find`](../../api/core/operators/find.md)
- [`findIndex`](../../api/core/operators/findindex.md)
- [`first`](../../api/core/operators/first.md)
- [`indexOf`](../../api/core/operators/indexof.md)
- [`isEmpty`](../../api/core/operators/isempty.md)
- [`last`](../../api/core/operators/last.md)
- [`lastIndexOf`](../../api/core/operators/lastindexof.md)
- [`max`](../../api/core/operators/max.md)
- [`maxBy`](../../api/core/operators/maxby.md)
- [`min`](../../api/core/operators/min.md)
- [`minBy`](../../api/core/operators/minby.md)
- [`reduce`](../../api/core/operators/reduce.md)
- [`sequenceEqual`](../../api/core/operators/sequenceequal.md)
- [`single`](../../api/core/operators/single.md)
- [`slice`](../../api/core/operators/slice.md)
- [`some`](../../api/core/operators/some.md)
- [`sum`](../../api/core/operators/sum.md)
- [`toMap`](../../api/core/operators/tomap.md)
- [`toSet`](../../api/core/operators/toset.md)
================================================
FILE: doc/libraries/lite/rx.lite.async.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Async Module #
The Reactive Extensions for JavaScript provides support for using generators with RxJS, as well as starting async methods or turning functions into async functions. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-async/rx.lite.async.js)
[`rx.lite.async.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-async-compat/rx.lite.async.compat.js)
NPM Packages:
- [`rx-lite-async`](https://www.npmjs.org/package/rx-lite-async)
- [`rx-lite-async-compat`](https://www.npmjs.org/package/rx-lite-async-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
### `Observable Methods`
- [`spawn`](../../api/core/operators/spawn.md)
- [`start`](../../api/core/operators/start.md)
- [`startAsync`](../../api/core/operators/startasync.md)
- [`toAsync`](../../api/core/operators/toasync.md)
================================================
FILE: doc/libraries/lite/rx.lite.coincidence.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Coincidence Module #
The Reactive Extensions for JavaScript has a set of coincidence-based operators such as `join` and `groupJoin` which allow one to correlate two observable sequences much as you would do in SQL. There is also support for advanced windowing and bufferring capabilities which allow for the specification of opening and closing observable sequences to denote how much data to capture. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-coincidence/rx.lite.coincidence.js)
- [`rx.lite.coincidence.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-coincidence-compat/rx.lite.coincidence.compat.js)
NPM Packages:
- [`rx-lite-coincidence`](https://www.npmjs.org/package/rx-lite-coincidence)
- [`rx-lite-coincidence-compat`](https://www.npmjs.org/package/rx-lite-coincidence-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
## `Observable Instance Methods`
- [`buffer`](../../api/core/operators/buffer.md)
- [`groupBy`](../../api/core/operators/groupby.md)
- [`groupByUntil`](../../api/core/operators/groupbyuntil.md)
- [`groupJoin`](../../api/core/operators/groupjoin.md)
- [`join`](../../api/core/operators/join.md)
- [`pairwise`](../../api/core/operators/pairwise.md)
- [`partition`](../../api/core/operators/partition.md)
- [`window`](../../api/core/operators/window.md)
================================================
FILE: doc/libraries/lite/rx.lite.experimental.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Experimental Module #
The Reactive Extensions for JavaScript has a number of operators that are considered experimental and not ready for mainstream usage. This includes imperative operators such as `if`, `case`, `for`, `while`, `doWhile` as well as operators such as `forkJoin`. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-experimental/rx.lite.experimental.js)
- [`rx.lite.experimental.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-experimental-compat/rx.lite.experimental.compat.js)
NPM Packages:
- [`rx-lite-experimental`](https://www.npmjs.org/package/rx-lite-experimental)
- [`rx-lite-experimental-compat`](https://www.npmjs.org/package/rx-lite-experimental-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
### `Observable Methods`
- [`case`](../../api/core/operators/case.md)
- [`for`](../../api/core/operators/for.md)
- [`forkJoin`](../../api/core/operators/forkjoin.md)
- [`if`](../../api/core/operators/if.md)
- [`while`](../../api/core/operators/while.md)
### `Observable Instance Methods`
- [`doWhile`](/api/core/operators/dowhile.md)
- [`expand`](../../api/core/operators/expand.md)
- [`extend`](../../api/core/operators/manyselect.md)
- [`flatMapFirst`](../../api/core/operators/flatmapfirst.md)
- [`flatMapWithMaxConcurrent`](../../api/core/flatmapwithmaxconcurrent.md)
- [`forkJoin`](../../api/core/operators/forkjoinproto.md)
- [`let`](../../api/core/operators/let.md)
- [`manySelect`](../../api/core/operators/manyselect.md)
- [`selectSwitchFirst`](../../api/core/operators/flatmapfirst.md)
- [`selectWithMaxConcurrent`](../../api/core/operators/flatmapwithmaxconcurrent.md)
================================================
FILE: doc/libraries/lite/rx.lite.extras.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Extras #
The Reactive Extensions for JavaScript's lite extras are the operators that are found on `rx.js` and `rx.compat.js` but not available in `rx.lite.js` and `rx.lite.compat.js`. By adding this file, you will have full access to all operators and thus makes including other files such as `rx.time.js`, `rx.joinpatterns.js` and others easier.
## Details ##
Files:
- [`rx.lite.extras.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.extras.js)
NPM Packages:
- [`rx-lite-extras`](https://www.npmjs.org/package/rx-lite-extras)
NuGet Packages:
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
### `Observable Methods`
- [`amb`](../../api/core/operators/amb.md)
- [`generate`](../../api/core/operators/generate.md)
- [`onErrorResumeNext`](../../api/core/operators/onerrorresumenext.md)
- [`using`](../../api/core/operators/using.md)
### `Observable Instance Methods`
- [`amb`](../../api/core/operators/ambproto.md)
- [`bufferWithCount`](../../api/core/operators/bufferwithcount.md)
- [`distinct`](../../api/core/operators/distinct.md)
- [`observeOn`](../../api/core/operators/observeon.md)
- [`onErrorResumeNext`](../../api/core/operators/onerrorresumenext.md)
- [`subscribeOn`](../../api/core/operators/subscribeon.md)
- [`takeLastBuffer`](../../api/core/operators/takelastbuffer.md)
- [`windowWithCount`](../../api/core/operators/windowwithcount.md)
================================================
FILE: doc/libraries/lite/rx.lite.joinpatterns.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Join Patterns Module #
The Reactive Extensions for JavaScript also supports join calculus in that you can easily create patterns for when certain observable sequences fire. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.joinpatterns.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-joinpatterns/rx.lite.joinpatterns.js)
-
[`rx.lite.joinpatterns.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-joinpatterns-compat/rx.lite.joinpatterns.compat.js)
NPM Packages:
- [`rx-lite-joinpatterns`](https://www.npmjs.org/package/rx-lite-joinpatterns)
- [`rx-lite-joinpatterns-compat`](https://www.npmjs.org/package/rx-lite-joinpatterns-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
### `Observable Methods`
- [`when`](../../api/core/operators/when.md)
### `Observable Instance Methods`
- [`and`](../../api/core/operators/and.md)
### `Pattern Instance Methods`
- [`thenDo`](../../api/core/operators/thendo.md)
================================================
FILE: doc/libraries/lite/rx.lite.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Module #
The Reactive Extensions for JavaScript Lite version is a lightweight version of the Reactive Extensions for JavaScript which covers most of the day to day operators you might use all in a single library. Functionality such as bridging to events, promises, callbacks, Node.js-style callbacks, time-based operations and more are built right in.
This comes with both `rx.lite.js` which is for use in modern development environments such as > IE9 and server-side environments such as Node.js. We also have `rx.lite.compat.js` which has backwards compatibility to browsers which do not support all required ES5 features.
## Details ##
Files:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx-lite`](https://www.npmjs.org/package/rx-lite)
NuGet Packages:
- [`RxJS-Lite`](https://www.nuget.org/packages/RxJS-Lite/)
## Included Observable Operators ##
### `Observable Methods`
- [`catch`](../../api/core/operators/catch.md)
- [`concat`](../../api/core/operators/concat.md)
- [`create`](../../api/core/operators/create.md)
- [`defer`](../../api/core/operators/defer.md)
- [`empty`](../../api/core/operators/empty.md)
- [`from`](../../api/core/operators/from.md)
- [`fromArray`](../../api/core/operators/fromarray.md)
- [`fromCallback`](../../api/core/operators/fromcallback.md)
- [`fromEvent`](../../api/core/operators/fromevent.md)
- [`fromEventPattern`](../../api/core/operators/fromeventpattern.md)
- [`fromNodeCallback`](../../api/core/operators/fromnodecallback.md)
- [`fromPromise`](../../api/core/operators/frompromise.md)
- [`interval`](../../api/core/operators/interval.md)
- [`just`](../../api/core/operators/return.md)
- [`merge`](../../api/core/operators/merge.md)
- [`mergeDelayError`](../../api/core/operators/mergedelayerror.md)
- [`never`](../../api/core/operators/never.md)
- [`of`](../../api/core/operators/of.md)
- [`ofWithScheduler`](../../api/core/operators/ofwithscheduler.md)
- [`pairs`](../../api/core/operators/pairs.md)
- [`range`](../../api/core/operators/range.md)
- [`repeat`](../../api/core/operators/repeat.md)
- [`return`](../../api/core/operators/return.md)
- [`throw`](../../api/core/operators/throw.md)
- [`timer`](../../api/core/operators/timer.md)
- [`zip`](../../api/core/operators/zip.md)
### `Observable Instance Methods`
- [`asObservable`](../../api/core/operators/asobservable.md)
- [`catch`](../../api/core/operators/catchproto.md)
- [`combineLatest`](../../api/core/operators/combinelatest.md)
- [`concat`](../../api/core/operators/concatproto.md)
- [`concatMap`](../../api/core/operators/concatmap.md)
- [`connect`](../../api/core/operators/connect.md)
- [`debounce`](../../api/core/operators/debounce.md)
- [`defaultIfEmpty`](../../api/core/operators/defaultifempty.md)
- [`delay`](../../api/core/operators/delay.md)
- [`dematerialize`](../../api/core/operators/dematerialize.md)
- [`distinctUntilChanged`](../../api/core/operators/distinctuntilchanged.md)
- [`do`](../../api/core/operators/do.md)
- [`doOnNext`](../../api/core/operators/doonnext.md)
- [`doOnError`](../../api/core/operators/doonerror.md)
- [`doOnCompleted`](../../api/core/operators/dooncompleted.md)
- [`filter`](../../api/core/operators/where.md)
- [`finally`](../../api/core/operators/finally.md)
- [`flatMap`](../../api/core/operators/selectmany.md)
- [`flatMapLatest`](../../api/core/operators/flatmaplatest.md)
- [`ignoreElements`](../../api/core/operators/ignoreelements.md)
- [`map`](../../api/core/operators/select.md)
- [`merge`](../../api/core/operators/mergeproto.md)
- [`mergeAll`](../../api/core/operators/mergeall.md)
- [`multicast`](../../api/core/operators/multicast.md)
- [`publish`](../../api/core/operators/publish.md)
- [`publishLast`](../../api/core/operators/publishlast.md)
- [`publishValue`](../../api/core/operators/publishvalue.md)
- [`refCount`](../../api/core/operators/refcount.md)
- [`repeat`](../../api/core/operators/repeat.md)
- [`repeatWhen`](../../api/core/operators/repeatwhen.md)
- [`replay`](../../api/core/operators/replay.md)
- [`retry`](../../api/core/operators/retry.md)
- [`retryWhen`](../../api/core/operators/retrywhen.md)
- [`sample`](../../api/core/operators/sample.md)
- [`scan`](../../api/core/operators/scan.md)
- [`select`](../../api/core/operators/select.md)
- [`selectConcat`](../../api/core/operators/concatmap.md)
- [`selectMany`](../../api/core/operators/selectmany.md)
- [`selectSwitch`](../../api/core/operators/flatmaplatest.md)
- [`singleInstance`](../../api/core/operators/singleinstance.md)
- [`skip`](../../api/core/operators/skip.md)
- [`skipLast`](../../api/core/operators/skiplast.md)
- [`skipUntil`](../../api/core/operators/skipuntil.md)
- [`skipWhile`](../../api/core/operators/skipwhile.md)
- [`startWith`](../../api/core/operators/startwith.md)
- [`subscribe | forEach`](../../api/core/operators/subscribe.md)
- [`subscribeOnNext`](../../api/core/operators/subscribeonnext.md)
- [`subscribeOnError`](../../api/core/operators/subscribeonerror.md)
- [`subscribeOnCompleted`](../../api/core/operators/subscribeoncompleted.md)
- [`switch | switchLatest`](../../api/core/operators/switch.md)
- [`take`](../../api/core/operators/take.md)
- [`takeLast`](../../api/core/operators/takelast.md)
- [`takeUntil`](../../api/core/operators/takeuntil.md)
- [`takeWhile`](../../api/core/operators/takewhile.md)
- [`tap`](../../api/core/operators/do.md)
- [`tapOnNext`](../../api/core/operators/doonnext.md)
- [`tapOnError`](../../api/core/operators/doonerror.md)
- [`tapOnCompleted`](../../api/core/operators/dooncompleted.md)
- [`throttle`](../../api/core/operators/throttle.md)
- [`timeout`](../../api/core/operators/timeout.md)
- [`timestamp`](../../api/core/operators/timestamp.md)
- [`toArray`](../../api/core/operators/toarray.md)
- [`toPromise`](../../api/core/operators/topromise.md)
- [`transduce`](../../api/core/operators/transduce.md)
- [`where`](../../api/core/operators/where.md)
- [`withLatestFrom`](../../api/core/operators/withlatestfrom.md)
- [`zip`](../../api/core/operators/zipproto.md)
- [`zipIterable`](../../api/core/operators/zipiterable.md)
## Included Classes ##
### Core Objects
- [`Rx.Observer`](../../api/core/observer.md)
- [`Rx.Notification`](../../api/core/notification.md)
### Subjects
- [`Rx.AsyncSubject`](../../api/subjects/asyncsubject.md)
- [`Rx.BehaviorSubject`](../../api/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](../../api/subjects/replaysubject.md)
- [`Rx.Subject`](../../api/subjects/subject.md)
### Schedulers
- [`Rx.Scheduler`](../../api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](../../api/disposables/compositedisposable.md)
- [`Rx.Disposable`](../../api/disposables/disposable.md)
- [`Rx.RefCountDisposable`](../../api/disposables/refcountdisposable.md)
- [`Rx.SerialDisposable`](../../api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](../../api/disposables/singleassignmentdisposable.md)
================================================
FILE: doc/libraries/lite/rx.lite.testing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Testing Module #
The Reactive Extensions for JavaScript has a built-in mechanism for testing all operators which allows for mocking absolute and relative time with ease. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-testing/rx.lite.testing.js)
- [`rx.lite.testing.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-testing-compat/rx.lite.testing.compat.js)
NPM Packages:
- [`rx-lite-testing`](https://www.npmjs.org/package/rx-lite-testing)
- [`rx-lite-testing-compat`](https://www.npmjs.org/package/rx-lite-testing-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Classes ##
### Testing Classes
- [`Rx.ReactiveTest`](../../api/testing/reactivetest.md)
- [`Rx.Recorded`](../../api/testing/recorded.md)
- [`Rx.Subscription`](../../api/testing/subscription.md)
- [`Rx.TestScheduler`](../../api/testing/testscheduler.md)
================================================
FILE: doc/libraries/lite/rx.lite.time.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Lite Time Module #
The Reactive Extensions for JavaScript, as it is a library that deals with events over time, naturally has a large number of operators that allow the creation of sequences at given timers, in addition to capturing time stamp and time interval information. In addition, you can also check for timeouts on your operations. This also supports windows and buffers with time. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-time/rx.lite.time.js)
- [`rx.lite.time.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-time-compat/rx.lite.time.compat.js)
NPM Packages:
- [`rx-lite-time`](https://www.npmjs.org/package/rx-lite-time)
- [`rx-lite-time-compat`](https://www.npmjs.org/package/rx-lite-time-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Observable Operators ##
### `Observable Methods`
- [`generateWithAbsoluteTime`](../../api/core/operators/generatewithabsolutetime.md)
- [`generateWithRelativeTime`](../../api/core/operators/generatewithrelativetime.md)
### `Observable Instance Methods`
- [`bufferWithTime`](../../api/core/operators/bufferwithtime.md)
- [`bufferWithTimeOrCount`](../../api/core/operators/bufferwithtimeorcount.md)
- [`delaySubscription`](../../api/core/operators/delaysubscription.md)
- [`sample`](../../api/core/operators/sample.md)
- [`skipLastWithTime`](../../api/core/operators/skiplastwithtime.md)
- [`takeLastBufferWithTime`](../../api/core/operators/takelastbufferwithtime.md)
- [`takeLastWithTime`](../../api/core/operators/takelastwithtime.md)
- [`timeInterval`](../../api/core/operators/timeinterval.md)
- [`timeout`](../../api/core/operators/timeout.md)
- [`timeoutWithSelector`](../../api/core/operators/timeoutwithselector.md)
- [`timestamp`](../../api/core/operators/timestamp.md)
- [`windowWithTime`](../../api/core/operators/windowwithtime.md)
- [`windowWithTimeOrCount`](../../api/core/operators/windowwithtimeorcount.md)
================================================
FILE: doc/libraries/lite/rx.lite.virtualtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Virtual Time Module #
The Reactive Extensions for JavaScript supports a notion of virtual time, which allows you to mock time easily, or even run through historical data through the `HistoricalScheduler`. This module is designed to work with the `rx-lite` NPM module for both the standards-compliant version as well as compat for older browsers.
## Details ##
Files:
- [`rx.lite.virtualtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-virtualtime/rx.lite.virtualtime.js)
- [`rx.lite.virtualtime.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/modules/rx-lite-virtualtime-compat/rx.lite.virtualtime.compat.js)
NPM Packages:
- [`rx-lite-virtualtime`](https://www.npmjs.org/package/rx-lite-virtualtime)
- [`rx-lite-virtualtime-compat`](https://www.npmjs.org/package/rx-lite-virtualtime-compat)
File Dependencies:
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js)
- [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
## Included Classes ##
### Schedulers
- [`Rx.HistoricalScheduler`](../../api/schedulers/historicalscheduler.md)
- [`Rx.VirtualTimeScheduler`](../../api/schedulers/virtualtimescheduler.md)
================================================
FILE: doc/libraries/main/rx.aggregates.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Aggregates Module #
The Reactive Extensions for JavaScript has a number of aggregation operators including those you might already know from the Array#extras and the upcoming ES6 standard such as `reduce`, `find` and `findIndex`. This module is used exclusively for aggregation operations used on finite observable sequences. In addition to the aforementioned operators, there are many useful operators such as `count`, `sum`, `average` and determining whether two sequences are equal via the `sequenceEqual` method.
## Details ##
Files:
- [`rx.aggregates.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.aggregates.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Aggregates`](http://www.nuget.org/packages/RxJS-Aggregates/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/) | [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
## Included Observable Operators ##
### `Observable Instance Methods`
- [`aggregate`](../../api/core/operators/reduce.md)
- [`all`](../../api/core/operators/every.md)
- [`any`](../../api/core/operators/some.md)
- [`average`](../../api/core/operators/average.md)
- [`includes`](../../api/core/operators/includes.md)
- [`count`](../../api/core/operators/count.md)
- [`elementAt`](../../api/core/operators/elementat.md)
- [`every`](../../api/core/operators/every.md)
- [`find`](../../api/core/operators/find.md)
- [`findIndex`](../../api/core/operators/findindex.md)
- [`first`](../../api/core/operators/first.md)
- [`indexOf`](../../api/core/operators/indexof.md)
- [`isEmpty`](../../api/core/operators/isempty.md)
- [`last`](../../api/core/operators/last.md)
- [`lastIndexOf`](../../api/core/operators/lastindexof.md)
- [`max`](../../api/core/operators/max.md)
- [`maxBy`](../../api/core/operators/maxby.md)
- [`min`](../../api/core/operators/min.md)
- [`minBy`](../../api/core/operators/minby.md)
- [`reduce`](../../api/core/operators/reduce.md)
- [`sequenceEqual`](../../api/core/operators/sequenceequal.md)
- [`single`](../../api/core/operators/single.md)
- [`slice`](../../api/core/operators/slice.md)
- [`some`](../../api/core/operators/some.md)
- [`sum`](../../api/core/operators/sum.md)
- [`toMap`](../../api/core/operators/tomap.md)
- [`toSet`](../../api/core/operators/toset.md)
================================================
FILE: doc/libraries/main/rx.async.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Async Module #
The Reactive Extensions for JavaScript provides support for bridging to events, promises, callbacks, Node.js-style callbacks and more. This module includes all of that functionality. In addition, this also supports taking ordinary functions and turning them into asynchronous functions via Observable sequences.
This comes with both `rx.async.js` which is for use in modern development environments such as > IE9 and server-side environments such as Node.js. We also have `rx.async.compat.js` which has backwards compatibility to browsers which do not support all required ES5 features.
## Details ##
Files:
- [`rx.async.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.async.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Async`](http://www.nuget.org/packages/RxJS-Async/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
## Included Observable Operators ##
### `Observable Methods`
- [`fromCallback`](../../api/core/operators/fromcallback.md)
- [`fromEvent`](../../api/core/operators/fromevent.md)
- [`fromEventPattern`](../../api/core/operators/fromeventpattern.md)
- [`fromNodeCallback`](../../api/core/operators/fromnodecallback.md)
- [`spawn`](../../api/core/operators/spawn.md)
- [`start`](../../api/core/operators/start.md)
- [`startAsync`](../../api/core/operators/startasync.md)
- [`toAsync`](../../api/core/operators/toasync.md)
- [`toPromise`](../../api/core/operators/topromise.md)
- [`wrap`](../../api/core/operators/wrap.md)
================================================
FILE: doc/libraries/main/rx.backpressure.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Backpressure Module #
The Reactive Extensions for JavaScript provides support backpressure for situations when the observable sequences emits too many messages for the observer to consume. This is in addition to other mechanisms already in place such as `buffer`, `throttle`, `sample` among other operators which allow you to get messages every so often, or in batches. This module allows you to pause and resume a hot observable with `pausable` and to pause and resume with buffered data with `pausableBuffered`. In addition, we also support the ability to get a requested number of items from the queue through the `controlled` operator.
## Details ##
Files:
- [`rx.backpressure.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.backpressure.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-BackPressure`](http://www.nuget.org/packages/RxJS-Backpressure/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
NuGet Dependencies:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
## Included Observable Operators ##
### `Observable Instance Methods`
- [`controlled`](../../api/core/operators/controlled.md)
- [`pausable`](../../api/core/operators/pausable.md)
- [`pausableBuffered`](../../api/core/operators/pausablebuffered.md)
================================================
FILE: doc/libraries/main/rx.binding.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Binding Module #
The Reactive Extensions for JavaScript has a notion of hot and cold observables. Hot observables fire whether you are listening to them or not, such as mouse movements. Cold observables on the other hand, such as a sequence created from an array will fire the same sequence to all subscribers. The Binding module gives you the ability to replay events for hot observables, and to turn cold observables into hot observables.
## Details ##
Files:
- [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js)
- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Binding`](http://www.nuget.org/packages/RxJS-Binding/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NuGet Dependencies:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
## Included Observable Operators ##
### `Observable Instance Methods`
- [`connect`](../../api/core/operators/connect.md)
- [`publish`](../../api/core/operators/publish.md)
- [`publishLast`](../../api/core/operators/publishlast.md)
- [`publishValue`](../../api/core/operators/publishvalue.md)
- [`refCount`](../../api/core/operators/refcount.md)
- [`replay`](../../api/core/operators/replay.md)
- [`share`](../../api/core/operators/share.md)
- [`shareLast`](../../api/core/operators/sharelast.md)
- [`shareReplay`](../../api/core/operators/sharereplay.md)
- [`shareValue`](../../api/core/operators/sharevalue.md)
- [`singleInstance`](../../api/core/operators/singleinstance.md)
## Included Classes ##
### Subjects
- [`Rx.BehaviorSubject`](../../api/core/observable.mdapi/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](../../api/core/observable.mdapi/subjects/replaysubject.md)
================================================
FILE: doc/libraries/main/rx.coincidence.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Coincidence Module #
The Reactive Extensions for JavaScript has a set of coincidence-based operators such as `join` and `groupJoin` which allow one to correlate two observable sequences much as you would do in SQL. There is also support for advanced windowing and bufferring capabilities which allow for the specification of opening and closing observable sequences to denote how much data to capture.
## Details ##
Files:
- [`rx.coincidence.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.coincidence.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Coincidence`](http://www.nuget.org/packages/RxJS-Coincidence/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
## Included Observable Operators ##
## `Observable Instance Methods`
- [`buffer`](../../api/core/operators/buffer.md)
- [`groupBy`](../../api/core/operators/groupby.md)
- [`groupByUntil`](../../api/core/operators/groupbyuntil.md)
- [`groupJoin`](../../api/core/operators/groupjoin.md)
- [`join`](../../api/core/operators/join.md)
- [`pairwise`](../../api/core/operators/pairwise.md)
- [`partition`](../../api/core/operators/partition.md)
- [`window`](../../api/core/operators/window.md)
================================================
FILE: doc/libraries/main/rx.complete.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Complete Module #
The Reactive Extensions for JavaScript's complete functionality is in the complete RxJS file which has many core components including the Schedulers, Disposables, Observable and Observer, but omits any testing capabilities.
This comes with both [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js) which is for use in modern development environments such as > IE9 and server-side environments such as Node.js. We also have [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js) which has backwards compatibility to browsers which do not support all required ES5 features.
## Details ##
Files:
- [`rx.all.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.js)
- [`rx.all.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.all.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
## Included Observable Operators ##
### `Observable Methods`
- [`amb`](../../api/core/operators/amb.md)
- [`case`](../../api/core/operators/case.md)
- [`catch`](../../api/core/operators/catch.md)
- [`concat`](../../api/core/operators/concat.md)
- [`create`](../../api/core/operators/create.md)
- [`defer`](../../api/core/operators/defer.md)
- [`empty`](../../api/core/operators/empty.md)
- [`for`](../../api/core/operators/for.md)
- [`forkJoin`](../../api/core/operators/forkjoin.md)
- [`from`](../../api/core/operators/from.md)
- [`fromArray`](../../api/core/operators/fromarray.md)
- [`fromCallback`](../../api/core/operators/fromcallback.md)
- [`fromEvent`](../../api/core/operators/fromevent.md)
- [`fromEventPattern`](../../api/core/operators/fromeventpattern.md)
- [`fromNodeCallback`](../../api/core/operators/fromnodecallback.md)
- [`fromPromise`](../../api/core/operators/frompromise.md)
- [`generate`](../../api/core/operators/generate.md)
- [`generateWithAbsoluteTime`](../../api/core/operators/generatewithabsolutetime.md)
- [`generateWithRelativeTime`](../../api/core/operators/generatewithrelativetime.md)
- [`if`](../../api/core/operators/if.md)
- [`interval`](../../api/core/operators/interval.md)
- [`just`](../../api/core/operators/return.md)
- [`merge`](../../api/core/operators/merge.md)
- [`mergeDelayError`](../../api/core/operators/mergedelayerror.md)
- [`never`](../../api/core/operators/never.md)
- [`of`](../../api/core/operators/of.md)
- [`ofArrayChanges`](../../api/core/operators/ofarraychanges.md)
- [`ofObjectChanges`](../../api/core/operators/ofobjectchanges.md)
- [`ofWithScheduler`](../../api/core/operators/ofwithscheduler.md)
- [`onErrorResumeNext`](../../api/core/operators/onerrorresumenext.md)
- [`pairs`](../../api/core/operators/pairs.md)
- [`range`](../../api/core/operators/range.md)
- [`repeat`](../../api/core/operators/repeat.md)
- [`return`](../../api/core/operators/return.md)
- [`spawn`](../../api/core/operators/spawn.md)
- [`start`](../../api/core/operators/start.md)
- [`startAsync`](../../api/core/operators/startasync.md)
- [`throw`](../../api/core/operators/throw.md)
- [`timer`](../../api/core/operators/timer.md)
- [`toAsync`](../../api/core/operators/toasync.md)
- [`using`](../../api/core/operators/using.md)
- [`when`](../../api/core/operators/when.md)
- [`while`](../../api/core/operators/while.md)
- [`wrap`](../../api/core/operators/wrap.md)
- [`zip`](../../api/core/operators/zip.md)
### `Observable Instance Methods`
- [`aggregate`](../../api/core/operators/reduce.md)
- [`all`](../../api/core/operators/every.md)
- [`amb`](../../api/core/operators/ambproto.md)
- [`and`](../../api/core/operators/and.md)
- [`any`](../../api/core/operators/some.md)
- [`asObservable`](../../api/core/operators/asobservable.md)
- [`average`](../../api/core/operators/average.md)
- [`buffer`](../../api/core/operators/buffer.md)
- [`bufferWithCount`](../../api/core/operators/bufferwithcount.md)
- [`bufferWithTime`](../../api/core/operators/bufferwithtime.md)
- [`bufferWithTimeOrCount`](../../api/core/operators/bufferwithtimeorcount.md)
- [`catch`](../../api/core/operators/catchproto.md)
- [`combineLatest`](../../api/core/operators/combinelatest.md)
- [`concat`](../../api/core/operators/concatproto.md)
- [`concatAll`](../../api/core/operators/concatall.md)
- [`concatMap`](../../api/core/operators/concatmap.md)
- [`connect`](../../api/core/operators/connect.md)
- [`controlled`](../../api/core/operators/controlled.md)
- [`count`](../../api/core/operators/count.md)
- [`debounce`](../../api/core/operators/debounce.md)
- [`defaultIfEmpty`](../../api/core/operators/defaultifempty.md)
- [`delay`](../../api/core/operators/delay.md)
- [`delaySubscription`](../../api/core/operators/delaysubscription.md)
- [`dematerialize`](../../api/core/operators/dematerialize.md)
- [`distinct`](../../api/core/operators/distinct.md)
- [`distinctUntilChanged`](../../api/core/operators/distinctuntilchanged.md)
- [`do`](../../api/core/operators/do.md)
- [`doOnNext`](../../api/core/operators/doonnext.md)
- [`doOnError`](../../api/core/operators/doonerror.md)
- [`doOnCompleted`](../../api/core/operators/dooncompleted.md)
- [`doWhile`](../../api/core/operators/dowhile.md)
- [`elementAt`](../../api/core/operators/elementat.md)
- [`every`](../../api/core/operators/every.md)
- [`expand`](../../api/core/operators/expand.md)
- [`extend`](../../api/core/operators/manyselect.md)
- [`filter`](../../api/core/operators/where.md)
- [`finally | ensure`](../../api/core/operators/finally.md)
- [`find`](../../api/core/operators/find.md)
- [`findIndex`](../../api/core/operators/findindex.md)
- [`first`](../../api/core/operators/first.md)
- [`flatMap`](../../api/core/operators/selectmany.md)
- [`flatMapFirst`](../../api/core/operators/flatmapfirst.md)
- [`flatMapLatest`](../../api/core/operators/flatmaplatest.md)
- [`flatMapObserver`](../../api/core/operators/flatmapobserver.md)
- [`flatMapWithMaxConcurrent`](../../api/core/flatmapwithmaxconcurrent.md)
- [`forkJoin`](../../api/core/operators/forkjoinproto.md)
- [`groupBy`](../../api/core/operators/groupby.md)
- [`groupByUntil`](../../api/core/operators/groupbyuntil.md)
- [`groupJoin`](../../api/core/operators/groupjoin.md)
- [`ignoreElements`](../../api/core/operators/ignoreelements.md)
- [`includes`](../../api/core/operators/includes.md)
- [`isEmpty`](../../api/core/operators/isempty.md)
- [`join`](../../api/core/operators/join.md)
- [`last`](../../api/core/operators/last.md)
- [`lastIndexOf`](../../api/core/operators/lastindexof.md)
- [`let`](../../api/core/operators/let.md)
- [`manySelect`](../../api/core/operators/manyselect.md)
- [`map`](../../api/core/operators/select.md)
- [`max`](../../api/core/operators/max.md)
- [`maxBy`](../../api/core/operators/maxby.md)
- [`merge`](../../api/core/operators/mergeproto.md)
- [`mergeAll`](../../api/core/operators/mergeall.md)
- [`min`](../../api/core/operators/min.md)
- [`minBy`](../../api/core/operators/minby.md)
- [`multicast`](../../api/core/operators/multicast.md)
- [`observeOn`](../../api/core/operators/observeon.md)
- [`onErrorResumeNext`](../../api/core/operators/onerrorresumenextproto.md)
- [`pairwise`](../../api/core/operators/pairwise.md)
- [`partition`](../../api/core/operators/partition.md)
- [`pausable`](../../api/core/operators/pausable.md)
- [`pausableBuffered`](../../api/core/operators/pausablebuffered.md)
- [`pluck`](../../api/core/operators/pluck.md)
- [`publish`](../../api/core/operators/publish.md)
- [`publishLast`](../../api/core/operators/publishlast.md)
- [`publishValue`](../../api/core/operators/publishvalue.md)
- [`share`](../../api/core/operators/share.md)
- [`shareReplay`](../../api/core/operators/sharereplay.md)
- [`shareValue`](../../api/core/operators/sharevalue.md)
- [`refCount`](../../api/core/operators/refcount.md)
- [`reduce`](../../api/core/operators/reduce.md)
- [`repeat`](../../api/core/operators/repeat.md)
- [`replay`](../../api/core/operators/replay.md)
- [`retry`](../../api/core/operators/retry.md)
- [`retryWhen`](../../api/core/operators/retrywhen.md)
- [`sample`](../../api/core/operators/sample.md)
- [`scan`](../../api/core/operators/scan.md)
- [`select`](../../api/core/operators/select.md)
- [`selectConcat`](../../api/core/operators/concatmap.md)
- [`selectMany`](../../api/core/operators/selectmany.md)
- [`selectManyObserver`](../../api/core/operators/selectmanyobserver.md)
- [`sequenceEqual`](../../api/core/operators/sequenceequal.md)
- [`single`](../../api/core/operators/single.md)
- [`singleInstance`](../../api/core/operators/singleinstance.md)
- [`skip`](../../api/core/operators/skip.md)
- [`skipLast`](../../api/core/operators/skiplast.md)
- [`skipLastWithTime`](../../api/core/operators/skiplastwithtime.md)
- [`skipUntil`](../../api/core/operators/skipuntil.md)
- [`skipUntilWithTime`](../../api/core/operators/skipuntilwithtime.md)
- [`skipWhile`](../../api/core/operators/skipwhile.md)
- [`slice`](../../api/core/operators/slice.md)
- [`some`](../../api/core/operators/some.md)
- [`startWith`](../../api/core/operators/startwith.md)
- [`subscribe | forEach`](../../api/core/operators/subscribe.md)
- [`subscribeOn`](../../api/core/operators/subscribeon.md)
- [`sum`](../../api/core/operators/sum.md)
- [`switch | switchLatest`](../../api/core/operators/switch.md)
- [`switchFirst`](../../api/core/operators/switchfirst.md)
- [`take`](../../api/core/operators/take.md)
- [`takeLast`](../../api/core/operators/takelast.md)
- [`takeLastBuffer`](../../api/core/operators/takelastbuffer.md)
- [`takeLastBufferWithTime`](../../api/core/operators/takelastbufferwithtime.md)
- [`takeLastWithTime`](../../api/core/operators/takelastwithtime.md)
- [`takeUntil`](../../api/core/operators/takeuntil.md)
- [`takeUntilWithTime`](../../api/core/operators/takeuntilwithtimee.md)
- [`takeWhile`](../../api/core/operators/takewhile.md)
- [`tap`](../../api/core/operators/do.md)
- [`tapOnNext`](../../api/core/operators/doonnext.md)
- [`tapOnError`](../../api/core/operators/doonerror.md)
- [`tapOnCompleted`](../../api/core/operators/dooncompleted.md)
- [`throttle`](../../api/core/operators/throttle.md)
- [`timeInterval`](../../api/core/operators/timeinterval.md)
- [`timeout`](../../api/core/operators/timeout.md)
- [`timestamp`](../../api/core/operators/timestamp.md)
- [`toArray`](../../api/core/operators/toarray.md)
- [`where`](../../api/core/operators/where.md)
- [`window`](../../api/core/operators/window.md)
- [`windowWithCount`](../../api/core/operators/windowwithcount.md)
- [`windowWithTime`](../../api/core/operators/windowwithtime.md)
- [`windowWithTimeOrCount`](../../api/core/operators/windowwithtimeorcount.md)
- [`withLatestFrom`](../../api/core/operators/withlatestfrom.md)
- [`zip`](../../api/core/operators/zipproto.md)
- [`zipIterable`](../../api/core/operators/zipiterable.md)
## Included Classes ##
### Core Objects
- [`Rx.Observer`](../../api/core/observer.md)
- [`Rx.Notification`](../../api/core/notification.md)
### Subjects
- [`Rx.AsyncSubject`](../../api/subjects/asyncsubject.md)
- [`Rx.Subject`](../../api/subjects/subject.md)
### Schedulers
- [`Rx.Scheduler`](../../api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](../../api/disposables/compositedisposable.md)
- [`Rx.Disposable`](../../api/disposables/disposable.md)
- [`Rx.RefCountDisposable`](../../api/disposables/refcountdisposable.md)
- [`Rx.SerialDisposable`](../../api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](../../api/disposables/singleassignmentdisposable.md)
================================================
FILE: doc/libraries/main/rx.experimental.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Experimental Module #
The Reactive Extensions for JavaScript has a number of operators that are considered experimental and not ready for mainstream usage. This includes imperative operators such as `if`, `case`, `for`, `while`, `doWhile` as well as operators such as `forkJoin`.
## Details ##
Files:
- [`rx.experimental.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.experimental.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Experimental`](http://www.nuget.org/packages/RxJS-Experimental/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
## Included Observable Operators ##
### `Observable Methods`
- [`case`](../../api/core/operators/case.md)
- [`for`](../../api/core/operators/for.md)
- [`forkJoin`](../../api/core/operators/forkjoin.md)
- [`if`](../../api/core/operators/if.md)
- [`while`](../../api/core/operators/while.md)
### `Observable Instance Methods`
- [`doWhile`](../../api/core/operators/dowhile.md)
- [`expand`](../../api/core/operators/expand.md)
- [`extend`](../../api/core/operators/manyselect.md)
- [`flatMapFirst`](../../api/core/operators/flatmapfirst.md)
- [`flatMapWithMaxConcurrent`](../../api/core/flatmapwithmaxconcurrent.md)
- [`forkJoin`](../../api/core/operators/forkjoinproto.md)
- [`let`](../../api/core/operators/let.md)
- [`manySelect`](../../api/core/operators/manyselect.md)
- [`selectSwitchFirst`](../../api/core/operators/flatmapfirst.md)
- [`selectWithMaxConcurrent`](../../api/core/operators/flatmapwithmaxconcurrent.md)
================================================
FILE: doc/libraries/main/rx.joinpatterns.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Join Patterns Module #
The Reactive Extensions for JavaScript also supports join calculus in that you can easily create patterns for when certain observable sequences fire.
## Details ##
Files:
- [`rx.joinpatterns.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.joinpatterns.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-JoinPatterns`](http://www.nuget.org/packages/RxJS-JoinPatterns/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
## Included Observable Operators ##
### `Observable Methods`
- [`when`](../../api/core/operators/when.md)
### `Observable Instance Methods`
- [`and`](../../api/core/operators/and.md)
### `Pattern Instance Methods`
- [`thenDo`](../../api/core/operators/thendo.md)
================================================
FILE: doc/libraries/main/rx.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Main Module #
The Reactive Extensions for JavaScript's main functionality is in the main RxJS file which has many core components including the Schedulers, Disposables, Observable and Observer.
This comes with both `rx.js` which is for use in modern development environments such as > IE9 and server-side environments such as Node.js. We also have `rx.compat.js` which has backwards compatibility to browsers which do not support all required ES5 features.
## Details ##
Files:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js)
- [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
## Included Observable Operators ##
### `Observable Methods`
- [`amb`](../../api/core/operators/amb.md)
- [`catch`](../../api/core/operators/catch.md)
- [`concat`](../../api/core/operators/concat.md)
- [`create`](../../api/core/operators/create.md)
- [`defer`](../../api/core/operators/defer.md)
- [`empty`](../../api/core/operators/empty.md)
- [`from`](../../api/core/operators/from.md)
- [`fromArray`](../../api/core/operators/fromarray.md)
- [`generate`](../../api/core/operators/generate.md)
- [`just`](../../api/core/operators/return.md)
- [`merge`](../../api/core/operators/merge.md)
- [`mergeDelayError`](../../api/core/operators/mergedelayerror.md)
- [`never`](../../api/core/operators/never.md)
- [`of`](../../api/core/operators/of.md)
- [`ofWithScheduler`](../../api/core/operators/ofwithscheduler.md)
- [`onErrorResumeNext`](../../api/core/operators/onerrorresumenext.md)
- [`pairs`](../../api/core/operators/pairs.md)
- [`range`](../../api/core/operators/range.md)
- [`repeat`](../../api/core/operators/repeat.md)
- [`return`](../../api/core/operators/return.md)
- [`throw`](../../api/core/operators/throw.md)
- [`zip`](../../api/core/operators/zip.md)
### `Observable Instance Methods`
- [`amb`](../../api/core/operators/ambproto.md)
- [`asObservable`](../../api/core/operators/asobservable.md)
- [`bufferWithCount`](../../api/core/operators/bufferwithcount.md)
- [`catch`](../../api/core/operators/catch.md)
- [`combineLatest`](../../api/core/operators/combinelatest.md)
- [`concat`](../../api/core/operators/concatproto.md)
- [`concatAll`](../../api/core/operators/concatall.md)
- [`concatMap`](../../api/core/operators/concatmap.md)
- [`defaultIfEmpty`](../../api/core/operators/defaultifempty.md)
- [`distinct`](../../api/core/operators/distinct.md)
- [`distinctUntilChanged`](../../api/core/operators/distinctuntilchanged.md)
- [`do`](../../api/core/operators/do.md)
- [`doOnNext`](../../api/core/operators/doonnext.md)
- [`doOnError`](../../api/core/operators/doonerror.md)
- [`doOnCompleted`](../../api/core/operators/dooncompleted.md)
- [`filter`](../../api/core/operators/where.md)
- [`finally`](../../api/core/operators/finally.md)
- [`flatMap`](../../api/core/operators/selectmany.md)
- [`flatMapLatest`](../../api/core/operators/flatmaplatest.md)
- [`flatMapObserver`](../../api/core/operators/flatmapobserver.md)
- [`ignoreElements`](../../api/core/operators/ignoreelements.md)
- [`map`](../../api/core/operators/select.md)
- [`merge`](../../api/core/operators/mergeproto.md)
- [`mergeAll`](../../api/core/operators/mergeall.md)
- [`observeOn`](../../api/core/operators/observeon.md)
- [`onErrorResumeNext`](../../api/core/operators/onerrorresumenext.md)
- [`repeat`](../../api/core/operators/repeatproto.md)
- [`repeatWhen`](../../api/core/operators/repeatwhen.md)
- [`retry`](../../api/core/operators/retry.md)
- [`retryWhen`](../../api/core/operators/retrywhen.md)
- [`scan`](../../api/core/operators/scan.md)
- [`select`](../../api/core/operators/select.md)
- [`selectConcat`](../../api/core/operators/concatmap.md)
- [`selectMany`](../../api/core/operators/selectmany.md)
- [`selectManyObserver`](../../api/core/operators/flatpmapobserver.md)
- [`selectSwitch`](../../api/core/operators/flatmaplatest.md)
- [`single`](../../api/core/operators/single.md)
- [`singleOrDefault`](../../api/core/operators/singleordefault.md)
- [`skip`](../../api/core/operators/skip.md)
- [`skipLast`](../../api/core/operators/skiplast.md)
- [`skipUntil`](../../api/core/operators/skipuntil.md)
- [`skipWhile`](../../api/core/operators/skipwhile.md)
- [`startWith`](../../api/core/operators/startwith.md)
- [`subscribe | forEach`](../../api/core/operators/subscribe.md)
- [`subscribeOnNext`](../../api/core/operators/subscribeonnext.md)
- [`subscribeOnError`](../../api/core/operators/subscribeonerror.md)
- [`subscribeOnCompleted`](../../api/core/operators/subscribeoncompleted.md)
- [`subscribeOn`](../../api/core/operators/subscribeon.md)
- [`switch | switchLatest`](../../api/core/operators/switch.md)
- [`take`](../../api/core/operators/take.md)
- [`takeLast`](../../api/core/operators/takelast.md)
- [`takeLastBuffer`](../../api/core/operators/takelastbuffer.md)
- [`takeUntil`](../../api/core/operators/takeuntil.md)
- [`takeWhile`](../../api/core/operators/takewhile.md)
- [`toArray`](../../api/core/operators/toarray.md)
- [`transduce`](../../api/core/operators/transduce.md)
- [`where`](../../api/core/operators/where.md)
- [`windowWithCount`](../../api/core/operators/windowwithcount.md)
- [`withLatestFrom`](../../api/core/operators/withlatestfrom.md)
- [`zip`](../../api/core/operators/zipproto.md)
- [`zipIterable`](../../api/core/operators/zipiterable.md)
## Included Classes ##
### Core Objects
- [`Rx.Observer`](../../api/core/observer.md)
- [`Rx.Observable`](../../api/core/observable.md)
- [`Rx.Notification`](../../api/core/notification.md)
### Subjects
- [`Rx.AsyncSubject`](../../api/subjects/asyncsubject.md)
- [`Rx.Subject`](../../api/subjects/subject.md)
### Schedulers
- [`Rx.Scheduler`](../../api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](../../api/disposables/compositedisposable.md)
- [`Rx.Disposable`](../../api/disposables/disposable.md)
- [`Rx.RefCountDisposable`](../../api/disposables/refcountdisposable.md)
- [`Rx.SerialDisposable`](../../api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](../../api/disposables/singleassignmentdisposable.md)
================================================
FILE: doc/libraries/main/rx.testing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Testing Module #
The Reactive Extensions for JavaScript has a built-in mechanism for testing all operators which allows for mocking absolute and relative time with ease.
## Details ##
Files:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.testing.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Testing`](http://www.nuget.org/packages/RxJS-Testing/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
- [`rx.virtualtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.virtualtime.js)
NuGet Dependencies:
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
## Included Classes ##
### Testing Classes
- [`Rx.ReactiveTest`](../../api/testing/reactivetest.md)
- [`Rx.Recorded`](../../api/testing/recorded.md)
- [`Rx.Subscription`](../../api/testing/subscription.md)
- [`Rx.TestScheduler`](../../api/testing/testscheduler.md)
================================================
FILE: doc/libraries/main/rx.time.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Time Module #
The Reactive Extensions for JavaScript, as it is a library that deals with events over time, naturally has a large number of operators that allow the creation of sequences at given timers, in addition to capturing time stamp and time interval information. In addition, you can also check for timeouts on your operations. This also supports windows and buffers with time.
## Details ##
Files:
- [`rx.time.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.time.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-Time`](http://www.nuget.org/packages/RxJS-Time/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
- [`RxJS-Lite`](http://www.nuget.org/packages/RxJS-Lite/)
## Included Observable Operators ##
### `Observable Methods`
- [`generateWithAbsoluteTime`](../../api/core/operators/generatewithabsolutetime.md)
- [`generateWithRelativeTime`](../../api/core/operators/generatewithrelativetime.md)
- [`interval`](../../api/core/operators/interval.md)
- [`timer`](../../api/core/operators/timer.md)
### `Observable Instance Methods`
- [`bufferWithTime`](../../api/core/operators/bufferwithtime.md)
- [`bufferWithTimeOrCount`](../../api/core/operators/bufferwithtimeorcount.md)
- [`debounce`](../../api/core/operators/debounce.md)
- [`delay`](../../api/core/operators/delay.md)
- [`delaySubscription`](../../api/core/operators/delaysubscription.md)
- [`sample`](../../api/core/operators/sample.md)
- [`skipLastWithTime`](../../api/core/operators/skiplastwithtime.md)
- [`takeLastBufferWithTime`](../../api/core/operators/takelastbufferwithtime.md)
- [`takeLastWithTime`](../../api/core/operators/takelastwithtime.md)
- [`throttle`](../../api/core/operators/throttle.md)
- [`timeInterval`](../../api/core/operators/timeinterval.md)
- [`timeout`](../../api/core/operators/timeout.md)
- [`timestamp`](../../api/core/operators/timestamp.md)
- [`windowWithTime`](../../api/core/operators/windowwithtime.md)
- [`windowWithTimeOrCount`](../../api/core/operators/windowwithtimeorcount.md)
================================================
FILE: doc/libraries/main/rx.virtualtime.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS Virtual Time Module #
The Reactive Extensions for JavaScript supports a notion of virtual time, which allows you to mock time easily, or even run through historical data through the `HistoricalScheduler`.
## Details ##
Files:
- [`rx.virtualtime.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.virtualtime.js)
NPM Packages:
- [`rx`](https://www.npmjs.org/package/rx)
NuGet Packages:
- [`RxJS-VirtualTime`](http://www.nuget.org/packages/RxJS-VirtualTime/)
File Dependencies:
- [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) | [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.lite.compat.js)
NuGet Dependencies:
- [`RxJS-All`](http://www.nuget.org/packages/RxJS-All/)
- [`RxJS-Main`](http://www.nuget.org/packages/RxJS-Main/)
## Included Classes ##
### Schedulers
- [`Rx.HistoricalScheduler`](../../api/schedulers/historicalscheduler.md)
- [`Rx.VirtualTimeScheduler`](../../api/schedulers/virtualtimescheduler.md)
================================================
FILE: doc/mapping/async/comparing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS for Async.js Users #
[Async.js](https://github.com/caolan/async) is a popular utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Async provides around 20 functions that include the usual 'functional' suspects (map, reduce, filter, each...) as well as some common patterns for asynchronous control flow (parallel, series, waterfall...). All these functions assume you follow the node.js convention of providing a single callback as the last argument of your async function.
Many of these concepts in the library map directly to RxJS concepts. We'll go operator by operator on how each map to existing functionality in RxJS.
## Collection Methods
- [`async.each`](#asynceach)
- [`async.map`](#asyncmap)
- [`async.filter`](#asyncfilter)
- [`async.reject`](#asyncreject)
- [`async.reduce`](#asyncreduce)
- [`async.detect`](#asyncdetect)
- [`async.some`](#asyncsome)
- [`async.every`](#asyncevery)
- [`async.concat`](#asynconcat)
## Control Flow
- [`async.series`](#asyncseries)
- [`async.parallel`](#asyncparallel)
- [`async.whilst`](#asyncwhilst)
- [`async.doWhilst`](#asyncdowhilst)
- [`async.nextTick`](#asyncnexttick)
- [`async.waterfall`](#asyncwaterfall)
- [`async.compose`](#asynccompose)
## `async.each` ##
The [`async.each`](https://github.com/caolan/async#eacharr-iterator-callback) method applies an iterator function to each item in an array, in parallel. The iterator is called with an item from the list and a callback for when it has finished. If the iterator passes an error to this callback, the main callback for the each function is immediately called with the error.
#### async version ####
In this example, we will use `async.each` to iterate an array of files to write some contents and save.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
function saveFile (file, cb) {
fs.writeFile(file, 'Hello Node', function (err) {
cb(err);
});
}
async.each(files, saveFile, function (err) {
// if any of the saves produced an error, err would equal that error
});
```
#### RxJS version ####
Using RxJS, you can accomplish this task in a number of ways by using `Rx.Observable.fromNodeCallback` to wrap the `fs.writeFile` function, and then iterate the files by using the `Rx.Observable.for` method.
```js
var Rx = require('rx'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
// wrap the method
var writeFile = Rx.Observable.fromNodeCallback(fs.writeFile);
Rx.Observable
.for(files, function (file) {
return writeFile(file, 'Hello Node')
})
.forEach(
function () {
console.log('file written!');
},
function (err) {
console.log('err ' + err);
},
function () {
console.log('completed!')
}
);
```
* * *
## `async.map` ##
The `async.map` method produces a new array of values by mapping each value in the given array through the iterator function. The iterator is called with an item from the array and a callback for when it has finished processing. The callback takes 2 arguments, an error and the transformed item from the array. If the iterator passes an error to this callback, the main callback for the map function is immediately called with the error.
#### async version ####
In this example, we'll get the `fs.stat` for each file given and have the results returned as an array.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
async.map(files, fs.stat, function (err, results) {
results.forEach(function (result) {
console.log('is file: %s', result.isFile());
});
});
```
#### RxJS version ####
Using RxJS, we can achieve the same results of an array of all of our values by wrapping the `fs.stat` method again using our `Rx.Observable.fromNodeCallback`, then iterate using the `Rx.Observable.for` method, and finally, calling `.toArray()` to get our results as an entire array.
```js
var Rx = require('rx'),
fs = require('fs');
var stat = Rx.Observable.fromNodeCallback(fs.stat);
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
Rx.Observable
.for(files, function (file) { return stat(file); })
.toArray()
.forEach(
function (results) {
results.forEach(function (result) {
console.log('is file: %s', result.isFile());
});
},
function (err) {
console.log('err %s', err);
}
);
```
* * *
## `async.filter` ##
The `async.filter` method returns a new array of all the values which pass an async truth test. The callback for each iterator call only accepts a single argument of true or false, it does not accept an error argument first! This is in-line with the way node libraries work with truth tests like fs.exists.
#### async version ####
In this example, we'll determine whether the file exists by calling `fs.exists` for each file given and have the results returned as an array.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
async.filter(files, fs.exists, function (results) {
results.forEach(function (result) {
console.log('exists: %s', result);
});
});
```
#### RxJS version ####
Using RxJS, we can achieve the same results of an array of all of our values by wrapping the `fs.exists` method using our `Rx.Observable.fromCallback` as it only has one result, a `true` or `false` value instead of the usual callback with error and result. Then we'll iterate using the `Rx.Observable.for` method, filter the existing files and finally, calling `.toArray()` to get our results as an entire array.
```js
var Rx = require('rx'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
var exists = Rx.Observable.fromCallback(fs.exists);
Rx.Observable
.for(files, function (file) { return exists(file); })
.where(function (x) { return x; })
.toArray()
.forEach(
function (results) {
results.forEach(function (result) {
console.log('exists: %s', result);
});
}
);
```
* * *
## `async.reject` ##
The `async.reject` method is the opposite of filter. Removes values that pass an async truth test.
#### async version ####
In this example, we'll determine whether the file exists by calling `fs.exists` for each file given and have the results returned as an array.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
async.reject(files, fs.exists, function (results) {
results.forEach(function (result) {
console.log('exists: %s', result);
});
});
```
#### RxJS version ####
Using RxJS, we can achieve the same results of an array of all of our values by wrapping the `fs.exists` method using our `Rx.Observable.fromCallback` as it only has one result, a `true` or `false` value instead of the usual callback with error and result. Then we'll iterate using the `Rx.Observable.for` method, filter the existing files using `filter` and finally, calling `.toArray()` to get our results as an entire array.
```js
var Rx = require('rx'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
var exists = Rx.Observable.fromCallback(fs.exists);
Rx.Observable
.for(files, function (file) { return exists(file); })
.where(function (x) { return !x; })
.toArray()
.forEach(
function (results) {
results.forEach(function (result) {
console.log('exists: %s', result);
});
}
);
```
* * *
## `async.reduce` ##
The `async.reduce` method reduces a list of values into a single value using an async iterator to return each successive step. Memo is the initial state of the reduction. This function only operates in series. For performance reasons, it may make sense to split a call to this function into a parallel map, then use the normal `Array.prototype.reduce` on the results. This function is for situations where each step in the reduction needs to be async, if you can get the data before reducing it then it's probably a good idea to do so.
#### async version ####
In this example, we'll call `reduction` for each value which will return the result of adding them all together.
```js
var async = require('async');
function reduction (acc, x, cb) {
process.nextTick(function () {
cb(null, acc + x);
});
}
async.reduce([1,2,3], 0, reduction, function (err, results) {
console.log(results);
});
// => 6
```
#### RxJS version ####
In RxJS, we have a number of ways of doing this including using `Rx.Observable.from` to turn an array into observable sequence, then we can call `reduce` to add the numbers. To ensure that it is indeed async, we can switch to the `Rx.Scheduler.timeout` to ensure that it is done via a `setImmediate` call.
```js
var Rx = require('rx');
Rx.Observable
.from([1,2,3], Rx.Scheduler.timeout)
.reduce(function (acc, x) { return acc + x; }, 0)
.forEach( function (results) { console.log(results); });
// => 6
```
* * *
## `async.detect` ##
The `async.detect` method returns the first value in a list that passes an async truth test. The iterator is applied in parallel, meaning the first iterator to return true will fire the detect callback with that result.
#### async version ####
In this example, we'll get the first file that matches.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
async.detect(files, fs.exists, function (result){
// result now equals the first file in the list that exists
});
```
#### RxJS version ####
In RxJS, we can iterate over the files as above using `Rx.Observable.from`, calling `concatMap` to call `fs.exists` and then calling `first` to get the first matching file project forward the file name and whether the file exists.
```js
var Rx = require('rx'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
var exists = Rx.Observable.fromCallback(fs.exists);
Rx.Observable
.from(files)
.concatMap(
function (file) { return exists(file); },
function (file, exists) { return {file: file, exists: exists}})
.first(function (x) { return x.exists; })
.forEach(
function (result) {
// result now equals the first file in the list that exists
});
```
* * *
## `async.some` ##
The `async.some` method returns `true` if at least one element in the array satisfies an async test. The callback for each iterator call only accepts a single argument of true or false, it does not accept an error argument first! This is in-line with the way node libraries work with truth tests like fs.exists. Once any iterator call returns true, the main callback is immediately called.
#### async version ####
In this example, we'll determine whether the file exists by calling `fs.exists` for each file given and have the results returned as an array.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
async.some(files, fs.exists, function (result){
// if result is true then at least one of the files exists
});
```
#### RxJS version ####
Using RxJS, we can achieve the same results of an array of all of our values by wrapping the `fs.exists` method using our `Rx.Observable.fromCallback` as it only has one result, a `true` or `false` value instead of the usual callback with error and result. Then we'll iterate using the `Rx.Observable.for` method, then call `some` to determine whether any match.
```js
var Rx = require('rx'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
var exists = Rx.Observable.fromCallback(fs.exists);
Rx.Observable
.for(files, function (file) { return exists(file); })
.some()
.forEach(
function (results) {
// if result is true then at least one of the files exists
});
```
* * *
## `async.every` ##
The `async.every` method returns `true` if every element in the array satisfies an async test. The callback for each iterator call only accepts a single argument of true or false, it does not accept an error argument first! This is in-line with the way node libraries work with truth tests like fs.exists.
#### async version ####
In this example, we'll determine whether the file exists by calling `fs.exists` for each file given and have the results returned as an array.
```js
var async = require('async'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
async.every(files, fs.exists, function (result) {
// if result is true then every file exists
});
```
#### RxJS version ####
Using RxJS, we can achieve the same results of an array of all of our values by wrapping the `fs.exists` method using our `Rx.Observable.fromCallback` as it only has one result, a `true` or `false` value instead of the usual callback with error and result. Then we'll iterate using the `Rx.Observable.for` method, then call `every` to determine whether all match.
```js
var Rx = require('rx'),
fs = require('fs');
var files = ['file1.txt', 'file2.txt', 'file3.txt'];
var exists = Rx.Observable.fromCallback(fs.exists);
Rx.Observable
.for(files, function (file) { return exists(file); })
.every(function (x) { return x; })
.forEach(
function (results) {
// if result is true then every file exists
});
```
* * *
## `async.concat` ##
The `async.concat` method applies an iterator to each item in a list, concatenating the results. Returns the concatenated list. The iterators are called in parallel, and the results are concatenated as they return.
#### async version ####
In this example, we'll determine whether the file exists by calling `fs.exists` for each file given and have the results returned as an array.
```js
var async = require('async'),
fs = require('fs');
var directories = ['dir1', 'dir2', 'dir3'];
async.concat(directories, fs.readdir, function (err, files) {
// files is now a list of filenames that exist in the 3 directories
});
```
#### RxJS version ####
Using RxJS, we can achieve the same results of an array of all of our values by wrapping the `fs.readdir` method using our `Rx.Observable.fromNodeCallback`. Then we'll iterate using the `Rx.Observable.for` method, then call `reduce` to add each item to the item to the overall list.
```js
var Rx = require('rx'),
fs = require('fs');
var directories = ['dir1', 'dir2', 'dir3'];
var readdir = Rx.Observable.fromNodeCallback(fs.readdir);
Rx.Observable
.for(directories, function (dir) { return readdir(dir); })
.reduce(function (acc, x) { return acc.concat(x) }, [])
.forEach(
function (files) {
// files is now a list of filenames that exist in the 3 directories
},
function (err) {
// handle error
});
```
* * *
## `async.series` ##
The `async.series` runs an array of functions in series, each one running once the previous function has completed. If any functions in the series pass an error to its callback, no more functions are run and the callback for the series is immediately called with the value of the error. Once the tasks have completed, the results are passed to the final callback as an array.
It is also possible to use an object instead of an array. Each property will be run as a function and the results will be passed to the final callback as an object instead of an array. This can be a more readable way of handling results from async.series.
#### async version ####
In this example we'll run some examples with both an array or an object.
```js
var async = require('async');
async.series([
function(callback){
// do some stuff ...
callback(null, 'one');
},
function(callback){
// do some more stuff ...
callback(null, 'two');
}
],
// optional callback
function(err, results){
// results is now equal to ['one', 'two']
});
// an example using an object instead of an array
async.series({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function(){
callback(null, 2);
}, 100);
}
},
function(err, results) {
// results is now equal to: {one: 1, two: 2}
});
```
#### RxJS version ####
We can achieve the same functionality of `async.series` with an array by simply calling `from` and calling `concatAll` to give us the observable of the current. Then we'll call `toArray` to add each item to a new array to return.
```js
var Rx = require('rx');
function wrapArray (items) {
return Rx.Observable
.from(items)
.concatAll()
.toArray();
}
wrapArray([
Rx.Observable.just('one'),
Rx.Observable.just('two')
])
.forEach(
function (results) {
console.log(results);
},
function (err) {
console.log('Error: %s', err);
}
);
// => ['one', 'two']
```
Using an object literal can also be achieved with a little bit more work in which we call `pairs` to get the key/value pairs from the object. Then we'll call `concatMap` to extract both the key, and the eventual value through the `map` function on the value's `Observable`. Then we can call `reduce` to build up a new object to return.
```js
var Rx = require('rx');
function wrapObject (obj) {
return Rx.Observable
.pairs(obj)
.concatMap(function (o) {
return o[1].map(function (v) { return [o[0], v]});
})
.reduce(function (acc, x) {
var obj = Object.create(acc);
obj[x[0]] = x[1];
return obj;
}, {});
}
wrapObject({
one: Rx.Observable.just(1),
two: Rx.Observable.just(2)
})
.forEach(
function (results) {
console.log(results);
},
function (err) {
console.log('Error: %s', err);
}
);
// => { one: 1, two: 2 }
```
* * *
## `async.parallel` ##
The `async.parallel` runs an array of functions in parallel, without waiting until the previous function has completed. If any of the functions pass an error to its callback, the main callback is immediately called with the value of the error. Once the tasks have completed, the results are passed to the final callback as an array.
It is also possible to use an object instead of an array. Each property will be run as a function and the results will be passed to the final callback as an object instead of an array. This can be a more readable way of handling results from async.parallel.
#### async version ####
In this example we'll run some examples with both an array or an object.
```js
var async = require('async');
async.parallel([
function(callback){
setTimeout(function(){
callback(null, 'one');
}, 200);
},
function(callback){
setTimeout(function(){
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results){
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});
// an example using an object instead of an array
async.parallel({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function(){
callback(null, 2);
}, 100);
}
},
function(err, results) {
// results is now equals to: {one: 1, two: 2}
});
```
#### RxJS version ####
We can achieve the same functionality of `async.parallel` with an array by calling `Rx.Observable.forkJoin` with our array of observable sequences. This returns the last value from each sequence in "parallel".
```js
var Rx = require('rx');
function wrapArrayParallel (items) {
return Rx.Observable.forkJoin.apply(null, items);
}
wrapArrayParallel([
Rx.Observable.just('one'),
Rx.Observable.just('two')
])
.forEach(
function (results) {
console.log(results);
},
function (err) {
console.log('Error: %s', err);
}
);
// => ['one', 'two']
```
Using an object literal can also be achieved with a little bit more work, but totally reasonable. Instead of simply calling `forkJoin`, we first need to extract the observable sequences by calling `map` on the keys we obtained by `Object.keys`. Because the order of observable sequences is deterministic, we can then call `map` to transform the array into an object, by calling `reduce` on the array, turning the array into an object with the appropriate keys.
```js
var Rx = require('rx');
function wrapObjectParallel (obj) {
var keys = Object.keys(obj);
var mapped = keys.map(function (key) {
return obj[key];
});
return Rx.Observable.forkJoin.apply(null, mapped)
.map(function (arr) {
var idx = 0;
return arr.reduce(function (acc, x) {
var o = Object.create(acc);
o[key[idx++]] = x;
return o;
}, {});
});
}
wrapObjectParallel({
one: Rx.Observable.just(1),
two: Rx.Observable.just(2)
})
.forEach(
function (results) {
console.log(results);
},
function (err) {
console.log('Error: ' + err);
}
);
// => { one: 1, two: 2 }
```
* * *
## `async.whilst` ##
The `async.whilst` method repeatedly call function, while test returns true. Calls the callback when stopped, or an error occurs.
#### async version ####
In this example we'll just run a keep calling the callback while the count is less than 5.
```js
var async = require('async');
var count = 0;
async.whilst(
function () { return count < 5; },
function (callback) {
count++;
setTimeout(callback, 1000);
},
function (err) {
// 5 seconds have passed
}
);
```
#### RxJS version ####
We can achieve the same kind of functionality by using the `Rx.Observable.while` method which takes a condition and an observable sequence that we created by calling `Rx.Observable.create`.
```js
var Rx = require('rx');
var count = 0;
Rx.Observable.while(
function () { return count < 5; },
Rx.Observable.create(function (observer) {
setTimeout(function () {
observer.onCompleted(count++);
}, 1000);
})
)
.subscribeOnCompleted(
function () { /* 5 seconds have passed */ }
);
```
* * *
## `async.doWhilst` ##
The `async.doWhilst` method is a post check version of `whilst`. To reflect the difference in the order of operations test and fn arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
#### async version ####
In this example we'll just run a keep calling the callback while the count is less than 5.
```js
var async = require('async');
var count = 0;
async.doWhilst(
function (callback) {
count++;
setTimeout(callback, 1000);
},
function () { return count < 5; },
function (err) {
// 5 seconds have passed
}
);
```
#### RxJS version ####
We can achieve the same kind of functionality by using the `doWhile` on our observable sequence which takes a predicate to determine whether to continue running.
```js
var Rx = require('rx');
var i = 0;
var source = Rx.Observable.timer(0, 1000).doWhile(
function () { return i++ < 5; })
.subscribeOnCompleted(
// 5 seconds have passed
);
```
* * *
## `async.nextTick` ##
The `async.nextTick` method calls the callback on a later loop around the event loop. In node.js this just calls process.nextTick, in the browser it falls back to setImmediate(callback) if available, otherwise setTimeout(callback, 0), which means other higher priority events may precede the execution of the callback.
#### async version ####
In this example we'll just run a keep calling the callback while the count is less than 5.
```js
var async = require('async');
var call_order = [];
async.nextTick( function () {
call_order.push('two');
// call_order now equals ['one','two']
});
call_order.push('one');
```
#### RxJS version ####
We can achieve the same thing by using the `Rx.Scheduler.timeout` scheduler to schedule an item which will optimize for the runtime, for example, using `process.nextTick` if available, or `setImmediate` if available, or other fallbacks like `MessageChannel`, `postMessage` or even an async script load.
```js
var Rx = require('rx');
var call_order = [];
Rx.Scheduler.timeout.schedule(function () {
call_order.push('two');
// call_order now equals ['one','two']
});
call_order.push('one');
```
* * *
## `async.waterfall` ##
The `async.waterfall` method runs an array of functions in series, each passing their results to the next in the array. However, if any of the functions pass an error to the callback, the next function is not executed and the main callback is immediately called with the error.
#### async version ####
In this example, we'll check whether a file exists, then rename it and finally return its [stats](http://nodejs.org/api/fs.html#fs_class_fs_stats).
```js
var async = require('async'),
fs = require('fs'),
path = require('path');
// Get file and destination
var file = path.join(__dirname, 'file.txt'),
dest = path.join(__dirname, 'file1.txt');
async.waterfall([
function (callback) {
fs.exists(file, function (flag) {
if (!flag) {
callback(new Error('File does not exist.'))
} else {
callback(null);
}
});
},
function (callback) {
fs.rename(file, dest, function (err) {
callback(err);
});
},
function (callback) {
fs.stat(dest, function (err, fsStat) {
callback(err, fsStat);
});
}
],
function (err, fsStat) {
if (err) {
console.log(err);
} else {
console.log(JSON.stringify(fsStat));
}
});
```
#### RxJS version ####
We can easily accomplish the same task as above using our wrappers for `Rx.Observable.fromCallback` and `Rx.Observable.fromNodeCallback`, creating a waterfall-like just using `concatMap`. We can now use it such as the following, wrapping `fs.exists`, `fs.rename` and `fs.stat`.
```js
var Rx = require('rx'),
fs = require('fs'),
path = require('path');
var file = path.join(__dirname, 'file.txt'),
dest = path.join(__dirname, 'file1.txt'),
exists = Rx.Observable.fromCallback(fs.exists),
rename = Rx.Observable.fromNodeCallback(fs.rename),
stat = Rx.Observable.fromNodeCallback(fs.stat);
exists(file)
.concatMap(function (flag) {
return flag ?
rename(file, dest) :
Rx.Observable.throw(new Error('File does not exist.'));
})
.concatMap(function () {
return stat(dest);
})
.forEach(
function (fsStat) {
console.log(JSON.stringify(fsStat));
},
function (err) {
console.log(err);
}
);
```
* * *
## `async.compose` ##
The [`async.compose`](https://github.com/caolan/async#composefn1-fn2) method creates a function which is a composition of the passed asynchronous functions. Each function consumes the return value of the function that follows. Composing functions f(), g() and h() would produce the result of f(g(h())), only this version uses callbacks to obtain the return values.
Each function is executed with the `this` binding of the composed function.
#### async version ####
In this example, we'll chain together two functions, one to add 1 to a supplied argument, and then chain it to another to multiply the result by 3.
```js
var async = require('async');
function add1(n, callback) {
setTimeout(function () {
callback(null, n + 1);
}, 10);
}
function mul3(n, callback) {
setTimeout(function () {
callback(null, n * 3);
}, 10);
}
var add1mul3 = async.compose(mul3, add1);
add1mul3(4, function (err, result) {
console.log(result);
});
// => 15
```
#### RxJS version ####
Using RxJS, we can accomplish this using the usual composition operator for sequential operations `concatMap`. We'll wrap the `setTimeout` with a `wrapTimeout` method and ensure that we do deterministic cleanup via `clearTimeout`. Then we can compose together our `add1` and `mul3` functions which result in observable sequences.
```js
var Rx = require('rx');
function wrapTimeout (fn, arg) {
return Rx.Observable.create(function (obs) {
// Ensure the composition of the this argument
var id = setTimeout(function () {
obs.onNext(fn.call(fn, arg));
obs.onCompleted();
}, 10);
// Handle cleanup/early disposal
return function () {
clearTimeout(id);
};
});
}
function add1 (n) {
return wrapTimeout(function (x) { return x + 1; }, n);
}
function mul3 (n) {
return wrapTimeout(function (x) { return x * 3; }, n);
}
add1(4)
.concatMap(mul3)
.forEach(
function (x) {
console.log(x);
},
function (err) {
console.log('Error: %s', e);
});
// => 15
```
* * *
================================================
FILE: doc/mapping/async/whyrx.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
================================================
FILE: doc/mapping/bacon.js/comparing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
================================================
FILE: doc/mapping/bacon.js/whyrx.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS for Bacon.js Users #
[Bacon.js](https://github.com/baconjs/bacon.js) is a popular Reactive Programming library which was inspired by RxJS, ReactiveBanana among other libraries.
But, before we get started, why use RxJS over Bacon.js?
### Performance ###
RxJS has always been committed to providing the best performance available on any given JavaScript platform. Whether it is providing a small footprint for an `Observable` instance, to providing the capability of using `setImmediate` versus `setTimeout` versus `requestAnimationFrame`, all by choosing a different scheduler. In addition, since RxJS is written in regular JavaScript versus CoffeeScript, there are a lot more optimizations that can be made by hand to ensure performance.
To make this more concrete, there is a project called [Kefir](https://github.com/rpominov/kefir) which is trying to make a more performance oriented version of Bacon.js. Here are some current numbers based upon the memory tests provided by Kefir. Note that these may change over time, but gives you a good indication of memory consumption. Below will be comparison of `combineLatest`, `filter`, `map`, and `scan`.
```
stream1.combine(stream2, ->) (1000 samples)
----------------------------------------------------------------
Kefir w/o subscr. 0.44 KiB w/ subscr. +0.80 KiB sum 1.23 KiB
Bacon w/o subscr. 5.42 KiB w/ subscr. +6.15 KiB sum 11.57 KiB
Rx w/o subscr. 0.43 KiB w/ subscr. +2.84 KiB sum 3.26 KiB
-----------------------
Kefir 1.00 1.00 1.00 Bacon 12.45 7.71 9.39 Rx 0.98 3.56 2.65
.filter(->) (1000 samples)
----------------------------------------------------------------
Kefir w/o subscr. 0.31 KiB w/ subscr. +0.46 KiB sum 0.77 KiB
Bacon w/o subscr. 1.82 KiB w/ subscr. +2.49 KiB sum 4.31 KiB
Rx w/o subscr. 0.37 KiB w/ subscr. +1.44 KiB sum 1.81 KiB
-----------------------
Kefir 1.00 1.00 1.00 Bacon 5.91 5.39 5.60 Rx 1.21 3.11 2.35
.map(->) (1000 samples)
----------------------------------------------------------------
Kefir w/o subscr. 0.30 KiB w/ subscr. +0.47 KiB sum 0.77 KiB
Bacon w/o subscr. 1.81 KiB w/ subscr. +2.49 KiB sum 4.30 KiB
Rx w/o subscr. 0.37 KiB w/ subscr. +1.43 KiB sum 1.81 KiB
-----------------------
Kefir 1.00 1.00 1.00 Bacon 6.07 5.31 5.60 Rx 1.24 3.06 2.35
.scan(0, ->) (1000 samples)
----------------------------------------------------------------
Kefir w/o subscr. 0.30 KiB w/ subscr. +0.47 KiB sum 0.76 KiB
Bacon w/o subscr. 1.68 KiB w/ subscr. +2.06 KiB sum 3.75 KiB
Rx w/o subscr. 0.39 KiB w/ subscr. +1.13 KiB sum 1.52 KiB
-----------------------
Kefir 1.00 1.00 1.00 Bacon 5.62 4.44 4.90 Rx 1.29 2.43 1.99
```
As you'll note, while Kefir does pretty well here, Bacon.js does not. Bacon.js has a fairly heavy Observable object to start with and then subscriptions are fairly heavy as well. With both Kefir and RxJS, the initial size of the Observable is about the same. We'll get to the other fine tuning such as schedulers in the later section.
## Interoperability With The Libraries You Use ##
One of the most important parts of when choosing a library is how well it works with the libraries you already use. Bacon.js ties itself directly to [jQuery](http://jquery.com) and [Zepto.js](http://zeptojs.com) for event binding with `asEventStream`. Not only that, but adding support for your own custom library's binding is difficult, whereas with RxJS it couldn't be easier.
RxJS, on the other hand is more flexible about binding to the libraries you use. For example, if you use [jQuery](http://jquery.com) or [Zepto.js](http://zeptojs.com), `Rx.Observable.fromEvent` will work perfectly for you. In addition, we also support the other libraries out of the box:
- [AngularJS](http://angularjs.org)
- [Backbone.js](http://backbonejs.org)
- [Ember.js](http://emberjs.com)
You can also override this behavior in `fromEvent` so that you use native DOM or Node.js events via the `EventEmitter` directly by setting the `Rx.config.useNativeEvents` flag to true, so that it's never in doubt which event system you are using. When using native DOM events, you can attach a listener to one item, or you can attach listeners to a NodeList's children, we figure that out for you without you having to change your code, whereas Bacon.js does not.
In order to support the libraries you use, it's very simple to add your own event binding, for example we can bind our events to the [Dojo Toolkit](http://dojotoolkit.org) using the `Rx.Observable.fromEventPattern` method:
```js
require(['dojo/on', 'dojo/dom', 'rx'], function (on, dom, rx) {
var input = dom.byId('input');
var source = Rx.Observable.fromEventPattern(
function addHandler (h) {
return on(input, 'click', h);
},
function delHandler (_, signal) {
signal.remove();
}
);
var subscription = source.subscribeOnNext(function (x) {
console.log('Next: Clicked!');
});
on.emit(input, 'click');
// => Next: Clicked!
});
```
In addition, transducers hold a great amount of potential for high performance querying, and to that end, RxJS has added [transducers support](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/transducers.md) via the `transduce` method.
```js
var t = transducers;
var source = Rx.Observable.range(1, 4);
function increment(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }
var transduced = source.transduce(t.comp(t.map(increment), t.filter(isEven)));
transduced.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function () { console.log('Completed'); });
// => Next: 2
// => Next: 4
// => Completed
```
## Browser Compatibility ##
Browser and runtime compatibility is important to RxJS. For example, it can run not only in the browser, but also Node.js, RingoJS, Narwhal, Nashorn, and event Windows Scripting Host (WSH). We realize that there are many users out there without access to the latest browser, so we do the best to accommodate this with our `compat` builds. These builds bridge all the way back to IE6 for support which includes using `attachEvent` with event normalization, to DOM Level 1 events. Bacon.js does not have this behavior, and instead falls back to hoping that you use jQuery.
We also want to build RxJS for speed with asynchronous operations, so we optimize for the browser and runtime you are using. For example, if your environment supports `setImmediate` for immediate execution, we will use that. Else, if you're in Node.js and `setImmediate` is not available, it falls back to `process.nextTick`. For browsers and runtimes that do not support `setImmediate`, we will fall back to `postMessage`, to `MessageChannel`, to asynchronous script loading, and finally defaulting back to `setTimeout` or event `WScript.Sleep` for Windows Scripting Host.
These `compat` files are important as we will shim behavior that we require such as `Array#extras`, `Function#bind` and so forth, so there is no need to bring in your own compatibility library such as html5shiv, although if they do exist already, we will use the native or shimmed methods directly.
## Standards Based ##
### Iterables and Array#extras ###
RxJS has a firm commitment to standards in JavaScript. Whether it is supporting the `Array#extras` standard method signatures such as `map`, `filter`, `reduce`, `every` and `some`, or to some new emerging standard on collections, RxJS will implement these features accordingly from pull collections to push. Unlike Bacon.js, RxJS conforms to `Array#extras` syntax to have the callback style of `function (item, index, collection)` in addition to accepting a `thisArg` for the calling context of the callback. This helps as you can easily reuse your code from the Array version to Observable version.
An example of forward thinking is the introduction of ES6+ operators on Array with implementations on Observable such as:
- `includes`
- `find`
- `findIndex`
- `from`
- `of`
In addition, RxJS supports ES6 iterables in many methods which allow you to accept `Map`, `Set`, `Array` and array-like objects, for example in `Rx.Observable.from`, `flatMap`, `concatMap` among others. RxJS also has the capability of converting to Maps and Sets via the `toMap` and `toSet` methods if available in your runtime.
This makes the following code possible to yield an array from an observable sequence and have it automatically converted into an observable sequence.
```js
Rx.Observable.range(1, 3)
.flatMap(function (x, i) { return [x, i]; })
.subscribeOnNext(function (value) {
console.log('Value: %o', value);
});
// => 1
// => 0
// => 2
// => 1
// => 3
// => 2
```
### Generators ###
Generators also play a big part in the next version of JavaScript. RxJS also takes [full advantage of generators](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/generators.md) as iterables in such methods as the aforementioned `Rx.Observable.from`, `flatMap`, `concatMap` and other methods. For example, you can yield values like the following:
```js
var source = Rx.Observable.from(
function* () { yield 1; yield 2; yield 3; }()
);
source.subscribeOnNext(function (value) {
console.log('Next: %s', value);
});
// => 1
// => 2
// => 3
```
Generators also give the developer pretty powerful capabilities when dealing with asynchronous actions. RxJS introduced the `Rx.Observable.spawn` method which allows you to write async/await style code over Observables, Promises, Arrays, and just plain objects.
```js
var spawned = Rx.Observable.spawn(function* () {
var x = yield Rx.Observable.just(42);
var y = yield Promise.resolve(42);
console.log(x + y);
try {
var source = yield Rx.Observable.throw(new Error('woops'));
console.log('Source is: %s', source);
} catch (e) {
console.log('Catched: %s', e.message);
}
});
spawned.subscribe();
// => 84
// => Source is: Error: woops
```
### Promises ###
Promises have been a great way for developers to express single value asynchronous values. With ES6, they have now been standardized and are starting to appear in all browsers. RxJS also supports `Promise` values as arguments in many places as noted in our [Bridging to Promises](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/promises.md) documentation. No more having to call `Rx.Observable.fromPromise` everywhere, RxJS automatically converts them for you.
```js
var source = Rx.Observable.fromEvent(input, 'keyup')
.map(function (e) { return e.target.value; })
.flatMapLatest(function (text) {
return queryPromise(text);
});
```
RxJS also allows an Observable sequence to be converted to an ES6 compliant `Promise` with the `toPromise` method.
```js
Rx.Observable.just(42)
.toPromise()
.then(function (value) {
console.log(value);
});
// => 42
```
## Swappable Concurrency Layer ##
RxJS can easily be described in three pieces. First the `Observer` and `Observable` objects, secondly by the operators for composition on top of them, and finally a swappable concurrency layer which allows you to swap out your concurrency model at any time. This last part is key which distinguishes RxJS from many other libraries. There are a number of advantages to this approach that may be subtle at first, but invaluable as you start to use them.
The first advantage is that you can switch where callbacks are executed, for example, instead of using `setImmediate` or any of its fallbacks, you can execute the callback on `window.requestAnimationFrame` for smooth animations.
```js
// Available in RxJS-DOM project
var scheduler = Rx.Scheduler.requestAnimationFrame;
function render(value) {
// Do something to render the value
}
Rx.Observable.range(1, 100, scheduler)
.subscribe(render);
```
Schedulers also have advantages with virtual time, which means we can say what time it really is. This is great for deterministic testing in which you can verify the behavior of every single operator. RxJS, through the `TestScheduler` can record when items happen and what values were yielded, thus no need for asynchronous testing.
```js
var scheduler = new TestScheduler();
var xs = scheduler.createHotObservable(
Rx.ReactiveTest.onNext(201, 1),
Rx.ReactiveTest.onCompleted(202)
);
var results = scheduler.startWithCreate(function () {
return xs.map(function (x, i) { return x + x + i });
});
// Some custom collection assertion for values
collectionAssert.assertEqual(results.messages, [
Rx.ReactiveTest.onNext(201, 2),
Rx.ReactiveTest.onCompleted(202)
]);
// Some custom collection assertion for subscriptions
collectionAssert.assertEqual(xs.subscriptions, [
Rx.ReactiveTest.subscribe(200, 202)
])
```
Every operator within RxJS has tests written in this style where all data is easily verified. Not only can we create observables through the `TestScheduler`, but we can create Promises via the `createResolvedPromise` and `createRejectedPromise` methods.
Virtual time has more advantages as well. Imagine if you had some historical stock data that you wanted to run through a simulation. Using the `Historical` scheduler, you can easily accomplish this.
```js
var scheduler = new Rx.HistoricalScheduler(new Date(2014, 1));
var source = new Rx.Subject();
getStockData().forEach(function (stock) {
scheduler.scheduleWithAbsolute(stock.date, function () {
stock.onNext(stock);
});
});
// Calculate with the data
source.groupBy(function (stock) { return stock.symbol; })
/* Do something with the data */
.subscribe(function (info) {
// Process the data
});
```
## Backpressure ##
In our applications, we consume a lot of data from external sources. But, what if our consumers (Observers) cannot handle the load from the observable sequence? RxJS has a number of mechanisms to handle this in the [Backpressure and Observable Sequences](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/backpressure.md) documentation. This could come in the form of lossy operations such as `debounce`, `throttleFirst`, `sample`, `pausable`, to loss-less operations such as `pausableBuffered`, `buffer`, etc.
## Build What You Want ##
RxJS has a rather large surface area, so we give you the ability to build RxJS with only the things you want and none of the things you don't via the [`rx-cli`](https://www.npmjs.org/package/rx-cli) project. For example, we can build a `compat` version of RxJS with only the `map`, `flatMap`, `takeUntil`, and `fromEvent` methods, which keeps your RxJS version lean and mean.
```bash
rx --lite --compat --methods map,flatmap,takeuntil,fromevent
```
## Long Stack Trace Support ##
Debugging programming with callbacks can be quite cumbersome. To that end, RxJS has introduced a notion of "Long Stack Traces" which allows you to quickly isolate your code from the plumbing not only of RxJS, but also Node.js and the browser cruft, thus getting you to the real cause of the issue.
For example, without "long stack trace" support, typically, an error would look like the following:
```js
var Rx = require('rx');
var source = Rx.Observable.range(0, 100)
.timestamp()
.map(function (x) {
if (x.value > 98) throw new Error();
return x;
});
source.subscribeOnError(
function (err) {
console.log(err.stack);
});
```
```bash
$ node example.js
Error
at C:\GitHub\example.js:6:29
at AnonymousObserver._onNext (C:\GitHub\rxjs\dist\rx.all.js:4013:31)
at AnonymousObserver.Rx.AnonymousObserver.AnonymousObserver.next (C:\GitHub\rxjs\dist\rx.all.js:1863:12)
at AnonymousObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AutoDetachObserverPrototype.next (C:\GitHub\rxjs\dist\rx.all.js:9226:23)
at AutoDetachObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AnonymousObserver._onNext (C:\GitHub\rxjs\dist\rx.all.js:4018:18)
at AnonymousObserver.Rx.AnonymousObserver.AnonymousObserver.next (C:\GitHub\rxjs\dist\rx.all.js:1863:12)
at AnonymousObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AutoDetachObserverPrototype.next (C:\GitHub\rxjs\dist\rx.all.js:9226:23)
```
This can be remedied using "long stack trace" support by setting the following flag:
```js
Rx.config.longStackSupport = true;
```
Then we can run our program again using this support
```bash
$ node example.js
Error
at C:\GitHub\example.js:6:29
From previous event:
at Object. (C:\GitHub\example.js:3:28)
From previous event:
at Object. (C:\GitHub\example.js:4:4)
From previous event:
at Object. (C:\GitHub\example.js:5:4)
```
## Many Examples and Tutorials ##
As people try to learn RxJS, it's always great to have [examples](https://github.com/Reactive-Extensions/RxJS/tree/master/examples) to get them started. To that end, RxJS ships a number of examples out of the box including simple scenarios such as Autocomplete, Follow the Mouse, Drawing, to more complete examples like databinding using a little demo project called `TKO`, to a complete game of Alphabet Invasion.
Want to learn RxJS at your own pace? We also have tutorials for that as well called [LearnRx](http://reactivex.io/learnrx/) which will walk you through the basics of learning to compose arrays, and then how that applies to observable sequences.
There are also many [community resources](https://github.com/Reactive-Extensions/RxJS#resources) to learn RxJS from videos, to presentations, to examples with integration with such libraries as AngularJS and React.
## Extensive Documentation ##
As stated before, RxJS has a rather large surface area so sometimes it's hard to know where to start. To that end, RxJS has [complete API documentation](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#reactive-extensions-class-library), as well as a [Getting Started Guide](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#getting-started-with-rxjs) as well as [Guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#rxjs-guidelines), a [How Do I?](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#how-do-i) section as well as a [growing list of comparisons with other libraries](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#mapping-rxjs-from-different-libraries).
================================================
FILE: doc/mapping/highland/comparing.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
================================================
FILE: doc/mapping/highland/whyrx.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS for Highland.js Users #
[Highland.js](http://highlandjs.org/) is a general purpose utility belt for handling both synchronous and asynchronous code. It is built upon node.js with EventEmitters and Streams with a focus on composition.
But, before we get started, why use RxJS over Highland.js?
### Uses an Array#extras interface instead of node.js Streams ###
Highland.js is built upon node.js infrastructure, including Streams. This is great if you're a node developer using streams, but there are many who do not and simply use callbacks and events. In addition, Streams are hard to get right, hence the changes between Streams 1, 2 and 3 with regards to pause/resume, high water marks, draining, etc. The [Streams Handbook](https://github.com/substack/stream-handbook) is a great way to get started looking at streams as an approach.
The Reactive Extensions are built on a language and runtime neutral approach that works great across languages, whether it is Java, .NET, Python, Ruby, Scala, Clojure, and JavaScript. This approach allows you easily to switch between Java, JavaScript, and .NET, and get a familiar feel between all the versions. RxJS was built upon the concept with the Array#extras in mind, where if you know Arrays in JavaScript, then you know RxJS. The only real difference is the possible element of time, and a push model instead of the Array's pull model.
For example, you can write the following using Arrays in JavaScript.
```js
var source = Array.of(1,2,3,4,5);
source
.map(function (x, i, a) { return x * x; })
.filter(function (x, i, a) { return x % 3 === 0; })
.forEach(function (x, i, a) {
console.log('next', x);
});
```
The same can then be done using RxJS with only one small code change of changing `Array` to `Rx.Observable`.
```js
var source = Rx.Observable.of(1,2,3,4,5);
source
.map(function (x, i, a) { return x * x; })
.filter(function (x, i, a) { return x % 3 === 0; })
.forEach(function (x, i, a) {
console.log('next', x);
});
```
### No Reliance on node.js Infrastructure ###
Highland.js is built upon node.js infrastructure using both the `EventEmitter` and `Stream` class which bring a number of dependencies with it for Browserify to make it work for the browser., including the many drawbacks of the ever changing Streams designs within node.js. As it interoperates with existing streams, they may or may not be well behaved in whether they will actually pause or not and whether backpressure actually works. These were key reasons for changes between Streams 1, 2 and 3.
Instead, RxJS takes a clean room approach with no external dependencies, which allows for a cleaner design without the technical debt of the `Stream` and `EventEmitter` designs in node.js. RxJS is built from scratch on a solid platform of the core objects of `Observer`, `Observable`, operators for composition, and `Scheduler` for controlling concurrency.
## Interoperability With Libraries and the DOM ##
One of the most important parts of when choosing a library is how well it works with the libraries you already use. Highland.js, by default, ties itself directly to [jQuery](http://jquery.com) or any kind of event emitter with an `on` method, such as [Zepto.js](http://zeptojs.com) for all DOM event binding, with no deterministic way of unbinding that added event handler. For everything else, `EventEmitters` are used for eventing.
RxJS, on the other hand is more flexible about binding to the libraries you use or to the plain old DOM. You can bind directly to the DOM elements using `Rx.Observable.fromEvent` which binds not only to a standard DOM Element, but also DOM NodeLists, etc directly, with deterministic disposal of events.
For external libraries, if you use [jQuery](http://jquery.com) or [Zepto.js](http://zeptojs.com), `Rx.Observable.fromEvent` will work perfectly for you. In addition, we also support the other libraries out of the box:
- [AngularJS](http://angularjs.org)
- [Backbone.js](http://backbonejs.org)
- [Ember.js](http://emberjs.org)
You can also override this behavior in `fromEvent` so that you use native DOM or Node.js events via the `EventEmitter` directly by setting the `Rx.config.useNativeEvents` flag to true, so that it's never in doubt which event system you are using. When using native DOM events, you can attach a listener to one item, or you can attach listeners to a NodeList's children, we figure that out for you without you having to change your code.
In order to support the libraries you use, it's very simple to add your own event binding, for example we can bind our events to the [Dojo Toolkit](http://dojotoolkit.org) using the `Rx.Observable.fromEventPattern` method:
```js
require(['dojo/on', 'dojo/dom', 'rx'], function (on, dom, rx) {
var input = dom.byId('input');
var source = Rx.Observable.fromEventPattern(
function addHandler (h) {
return on(input, 'click', h);
},
function delHandler (_, signal) {
signal.remove();
}
);
var subscription = source.subscribeOnNext(function (x) {
console.log('Next: Clicked!');
});
on.emit(input, 'click');
// => Next: Clicked!
});
```
In addition, transducers hold a great amount of potential for high performance querying, and to that end, RxJS has added [transducers support](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/transducers.md) via the `transduce` method.
```js
var t = transducers;
var source = Rx.Observable.range(1, 4);
function increment(x) { return x + 1; }
function isEven(x) { return x % 2 === 0; }
var transduced = source.transduce(t.comp(t.map(increment), t.filter(isEven)));
transduced.subscribe(
function (x) { console.log('Next: %s', x); },
function (e) { console.log('Error: %s', e); },
function () { console.log('Completed'); });
// => Next: 2
// => Next: 4
// => Completed
```
## Browser Compatibility ##
Browser and runtime compatibility is important to RxJS. For example, it can run not only in the browser, but also Node.js, RingoJS, Narwhal, Nashorn, and even Windows Scripting Host (WSH). We realize that there are many users out there without access to the latest browser, so we do the best to accommodate this with our `compat` builds. These builds bridge all the way back to IE6 for support which includes using `attachEvent` with event normalization, to DOM Level 1 events. Highland.js does not have this behavior, and instead relies solely on `EventEmitter` or jQuery for events support.
We also want to build RxJS for speed with asynchronous operations, so we optimize for the browser and runtime you are using. For example, if your environment supports `setImmediate` for immediate execution, we will use that. Else, if you're in Node.js and `setImmediate` is not available, it falls back to `process.nextTick`. For browsers and runtimes that do not support `setImmediate`, we will fall back to `postMessage`, to `MessageChannel`, to asynchronous script loading, and finally defaulting back to `setTimeout` or event `WScript.Sleep` for Windows Scripting Host.
These `compat` files are important as we will shim behavior that we require such as `Array#extras`, `Function#bind` and so forth, so there is no need to bring in your own compatibility library such as html5shiv, although if they do exist already, we will use the native or shimmed methods directly.
## Standards Based ##
### Iterables and Array#extras ###
RxJS has a firm commitment to standards in JavaScript. Whether it is supporting the `Array#extras` standard method signatures such as `map`, `filter`, `reduce`, `every` and `some`, or to some new emerging standard on collections, RxJS will implement these features accordingly from pull collections to push. Unlike Highland.js, RxJS conforms to `Array#extras` syntax to have the callback style of `function (item, index, collection)` in addition to accepting a `thisArg` for the calling context of the callback. This helps as you can easily reuse your code from the Array version to Observable version.
An example of forward thinking is the introduction of ES6+ operators on Array with implementations on Observable such as:
- `includes`
- `find`
- `findIndex`
- `from`
- `of`
In addition, RxJS supports ES6 iterables in many methods which allow you to accept `Map`, `Set`, `Array` and array-like objects, for example in `Rx.Observable.from`, `flatMap`, `concatMap` among others. RxJS also has the capability of converting to Maps and Sets via the `toMap` and `toSet` methods if available in your runtime.
This makes the following code possible to yield an array from an observable sequence and have it automatically converted into an observable sequence.
```js
Rx.Observable.range(1, 3)
.flatMap(function (x, i) { return [x, i]; })
.subscribeOnNext(function (value) {
console.log('Value: %o', value);
});
// => 1
// => 0
// => 2
// => 1
// => 3
// => 2
```
### Generators ###
Generators also play a big part in the next version of JavaScript. RxJS also takes [full advantage of generators](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/generators.md) as iterables in such methods as the aforementioned `Rx.Observable.from`, `flatMap`, `concatMap` and other methods. For example, you can yield values like the following:
```js
var source = Rx.Observable.from(
function* () { yield 1; yield 2; yield 3; }()
);
source.subscribeOnNext(function (value) {
console.log('Next: %s', value);
});
// => 1
// => 2
// => 3
```
Generators also give the developer pretty powerful capabilities when dealing with asynchronous actions. RxJS introduced the `Rx.spawn` method which allows you to write async/await style code over Observables, Promises, Arrays, and just plain objects.
```js
Rx.spawn(function* () {
var x = yield Rx.Observable.just(42);
var y = yield Promise.resolve(42);
console.log(x + y);
try {
var source = yield Rx.Observable.throwError(new Error('woops'));
} catch (e) {
console.log(e.message);
}
})();
// => 84
// => woops
```
### Promises ###
Promises have been a great way for developers to express single value asynchronous values. With ES6, they have now been standardized and are starting to appear in all browsers. RxJS also supports `Promise` values as arguments in many places as noted in our [Bridging to Promises](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/promises.md) documentation. No more having to call `Rx.Observable.fromPromise` everywhere, RxJS automatically converts them for you.
```js
var source = Rx.Observable.fromEvent(input, 'keyup')
.map(function (e) { return e.target.value; })
.flatMapLatest(function (text) {
return queryPromise(text);
});
```
RxJS also allows an Observable sequence to be converted to an ES6 compliant `Promise` with the `toPromise` method.
```js
Rx.Observable.just(42)
.toPromise()
.then(function (value) {
console.log(value);
});
// => 42
```
## Swappable Concurrency Layer ##
RxJS can easily be described in three pieces. First the `Observer` and `Observable` objects, secondly by the operators for composition on top of them, and finally a swappable concurrency layer which allows you to swap out your concurrency model at any time. This last part is key which distinguishes RxJS from many other libraries. There are a number of advantages to this approach that may be subtle at first, but invaluable as you start to use them.
The first advantage is that you can switch where callbacks are executed, for example, instead of using `setImmediate` or any of its fallbacks, you can execute the callback on `window.requestAnimationFrame` for smooth animations.
```js
// Available in RxJS-DOM project
var scheduler = Rx.Scheduler.requestAnimationFrame;
function render(value) {
// Do something to render the value
}
Rx.Observable.range(1, 100, scheduler)
.subscribe(render);
```
Schedulers also have advantages with virtual time, which means we can say what time it really is. This is great for deterministic testing in which you can verify the behavior of every single operator. RxJS, through the `TestScheduler` can record when items happen and what values were yielded, thus no need for asynchronous testing.
```js
var scheduler = new TestScheduler();
var xs = scheduler.createHotObservable(
Rx.ReactiveTest.onNext(201, 1),
Rx.ReactiveTest.onCompleted(202)
);
var results = scheduler.startWithCreate(function () {
return xs.map(function (x, i) { return x + x + i });
});
// Some custom collection assertion for values
collectionAssert.assertEqual(results.messages, [
Rx.ReactiveTest.onNext(201, 2),
Rx.ReactiveTest.onCompleted(202)
]);
// Some custom collection assertion for subscriptions
collectionAssert.assertEqual(xs.subscriptions, [
Rx.ReactiveTest.subscribe(200, 202)
])
```
Every operator within RxJS has tests written in this style where all data is easily verified. Not only can we create observables through the `TestScheduler`, but we can create Promises via the `createResolvedPromise` and `createRejectedPromise` methods.
Virtual time has more advantages as well. Imagine if you had some historical stock data that you wanted to run through a simulation. Using the `Historical` scheduler, you can easily accomplish this.
```js
var scheduler = new Rx.HistoricalScheduler(new Date(2014, 1));
var source = new Rx.Subject();
getStockData().forEach(function (stock) {
scheduler.scheduleWithAbsolute(stock.date, function () {
stock.onNext(stock);
});
});
// Calculate with the data
source.groupBy(function (stock) { return stock.symbol })
/* Do something with the data */
.subscribe(function (info) {
// Process the data
});
```
## Multicast Backpressure ##
In our applications, we consume a lot of data from external sources. But, what if our consumers cannot handle the load from the sequence?
Highland.js uses the standard backpressure mechanisms such as `pause`/`resume` from standard node.js streams, as well as `throttle` and `debounce` for lossy operations. The pause/resume from normal node.js streams work for multicast streams to share backpressure via `fork`, or to keep them separate with `observe`, but this can sometimes lead to confusion, especially when mixed.
RxJS has a number of mechanisms to handle this in the [Backpressure and Observable Sequences](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/backpressure.md) documentation. This could come in the form of lossy operations such as `debounce`, `throttleFirst`, `sample`, `pausable`, to loss-less operations such as `pausableBuffered`, `buffer`, `windowed`, `stopAndWait`, etc. These work on the idea of multicast streams so that one consumer is not punished by another's inability to process the data in a timely manner.
In RxJS, you can synchronize across streams with backpressure with the pause/resume semantics using a `Pauser` or just any ordinary `Subject` with `onNext(true)` to resume and `onNext(false)` to pause:
```js
var pauser = new Rx.Pauser();
var source1 = getData().pausableBuffered(pauser);
var source2 = getOtherData().pausableBuffered(pauser);
// To pause both streams
pauser.pause();
// To resume both streams
pauser.resume();
```
## Build What You Want ##
RxJS has a rather large surface area, so we give you the ability to build RxJS with only the things you want and none of the things you don't via the [`rx-cli`](https://www.npmjs.org/package/rx-cli) project. For example, we can build a `compat` version of RxJS with only the `map`, `flatMap`, `takeUntil`, and `fromEvent` methods, which keeps your RxJS version lean and mean.
```bash
rx --lite --compat --methods map,flatmap,takeuntil,fromevent
```
## Long Stack Trace Support ##
Debugging programming with callbacks can be quite cumbersome. To that end, RxJS has introduced a notion of "Long Stack Traces" which allows you to quickly isolate your code from the plumbing not only of RxJS, but also node.js and the browser cruft, thus getting you to the real cause of the issue.
For example, without "long stack trace" support, typically, an error would look like the following:
```js
var Rx = require('rx');
var source = Rx.Observable.range(0, 100)
.timestamp()
.map(function (x) {
if (x.value > 98) throw new Error();
return x;
});
source.subscribeOnError(
function (err) {
console.log(err.stack);
});
```
```bash
$ node example.js
Error
at C:\GitHub\example.js:6:29
at AnonymousObserver._onNext (C:\GitHub\rxjs\dist\rx.all.js:4013:31)
at AnonymousObserver.Rx.AnonymousObserver.AnonymousObserver.next (C:\GitHub\rxjs\dist\rx.all.js:1863:12)
at AnonymousObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AutoDetachObserverPrototype.next (C:\GitHub\rxjs\dist\rx.all.js:9226:23)
at AutoDetachObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AnonymousObserver._onNext (C:\GitHub\rxjs\dist\rx.all.js:4018:18)
at AnonymousObserver.Rx.AnonymousObserver.AnonymousObserver.next (C:\GitHub\rxjs\dist\rx.all.js:1863:12)
at AnonymousObserver.Rx.internals.AbstractObserver.AbstractObserver.onNext (C:\GitHub\rxjs\dist\rx.all.js:1795:35)
at AutoDetachObserverPrototype.next (C:\GitHub\rxjs\dist\rx.all.js:9226:23)
```
This can be remedied using "long stack trace" support by setting the following flag:
```js
Rx.config.longStackSupport = true;
```
Then we can run our program again using this support
```bash
$ node example.js
Error
at C:\GitHub\example.js:6:29
From previous event:
at Object. (C:\GitHub\example.js:3:28)
From previous event:
at Object. (C:\GitHub\example.js:4:4)
From previous event:
at Object. (C:\GitHub\example.js:5:4)
```
## Many Examples and Tutorials ##
As people try to learn RxJS, it's always great to have [examples](https://github.com/Reactive-Extensions/RxJS/tree/master/examples) to get them started. To that end, RxJS ships a number of examples out of the box including simple scenarios such as Autocomplete, Follow the Mouse, Drawing, to more complete examples like databinding using a little demo project called `TKO`, to a complete game of Alphabet Invasion.
Want to learn RxJS at your own pace? We also have tutorials for that as well called [LearnRx](http://jhusain.github.io/learnrx/) which will walk you through the basics of learning to compose arrays, and then how that applies to observable sequences.
There are also many [community resources](https://github.com/Reactive-Extensions/RxJS#resources) to learn RxJS from videos, to presentations, to examples with integration with such libraries as AngularJS and React.
## Extensive Documentation ##
As stated before, RxJS has a rather large surface area so sometimes it's hard to know where to start. To that end, RxJS has [complete API documentation](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#reactive-extensions-class-library), as well as a [Getting Started Guide](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#getting-started-with-rxjs) as well as [Guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#rxjs-guidelines), a [How Do I?](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#how-do-i) section as well as a [growing list of comparisons with other libraries](https://github.com/Reactive-Extensions/RxJS/tree/master/doc#mapping-rxjs-from-different-libraries).
================================================
FILE: doc/readme.md
================================================
# This is RxJS v 4. [Find the latest version here](https://github.com/reactivex/rxjs)
# RxJS v4.0
Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators.
Data sequences can take many forms, such as a stream of data from a file or web service, web services requests, system notifications, or a series of events such as user input.
Reactive Extensions represents all these data sequences as observable sequences. An application can subscribe to these observable sequences to receive asynchronous notifications as new data arrive.
RxJS has no dependencies which complements and interoperates smoothly with both synchronous data streams such as iterable objects in JavaScript and single-value asynchronous computations such as Promises as the following diagram shows:
Single return value
Multiple return values
Pull/Synchronous/Interactive
Object
Iterables(Array | Set | Map)
Push/Asynchronous/Reactive
Promise
Observable
To put it more concretely, if you know how to program against Arrays using the Array#extras, then you already know how to use RxJS!
Example code showing how similar high-order functions can be applied to an Array and an Observable
Iterable
Observable
getDataFromLocalMemory()
.filter(s => s != null)
.map(s => s + 'transformed')
.forEach(s => console.log(\`next => ${s}\`))
getDataFromNetwork()
.filter(s => s != null)
.map(s => s + 'transformed')
.subscribe(s => console.log(\`next => ${s}\`))
There are a number of ways of getting started with RxJS including:
- [Getting Started With RxJS](#getting-started-with-rxjs)
- [RxJS Guidelines](#rxjs-guidlines)
- [Getting to Know RxJS Libraries](#getting-to-know-rxjs-libraries)
- [How Do I?](#how-do-i)
- [Mapping RxJS from Different Libraries](#mapping-rxjs-from-different-libraries)
- [API Documentation](#reactive-extensions-class-library)
## Getting Started With RxJS
Getting started with the Reactive Extensions for JavaScript is easy. Let's start with the basics here:
- [What are the Reactive Extensions?](gettingstarted/what.md)
- [Exploring Major Concepts in RxJS](gettingstarted/exploring.md)
- [Creating and Querying Observable Sequences](gettingstarted/creatingquerying.md)
1. [Creating and Subscribing to Simple Observable Sequences](gettingstarted/creating.md)
2. [Bridging to Events](gettingstarted/events.md)
3. [Bridging to Callbacks](gettingstarted/callbacks.md)
4. [Bridging to Promises](gettingstarted/promises.md)
5. [Generators and Observable Sequences](gettingstarted/generators.md)
6. [Querying Observable Sequences](gettingstarted/querying.md)
7. [Error Handling With Observable Sequences](gettingstarted/errors.md)
8. [Transducers with Observable Sequences](gettingstarted/transducers.md)
9. [Backpressure with Observable Sequences](gettingstarted/backpressure.md)
10. [Operators by Category](gettingstarted/categories.md)
11. Which Operator do I use?
- [Creation Operators](gettingstarted/which-static.md)
- [Instance Operators](gettingstarted/which-instance.md)
- [Subjects](gettingstarted/subjects.md)
- [Scheduling and Concurrency](gettingstarted/schedulers.md)
- [Testing and Debugging](gettingstarted/testing.md)
- [Implementing Your Own Operators](gettingstarted/operators.md)
## RxJS Guidelines ##
Curious on how we designed RxJS? This is covered along with overall guidelines of how your RxJS code should operate. In addition, we have contribution guidelines which set the bar for which we accept contributions.
- [RxJS Code of Conduct](https://github.com/Reactive-Extensions/RxJS/tree/master/code-of-conduct.md)
- [RxJS Design Guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/designguidelines)
- [RxJS Contribution Guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/contributing.md)
## Getting to Know RxJS Libraries ##
There are many libraries that make up the Reactive Extensions for JavaScript, so it may be a little daunting at first to know which ones to include. This will serve as a guide for which libraries you might need. For most operations you'll only need [`rx.lite.js`](libraries/lite/rx.lite.md), but you may find you need more operators, so you start with [`rx.js`](libraries/main/rx.md) and add additional files to mix in functionality as you need it.
### The complete library:
- [`rx.all.js`](libraries/main/rx.complete.md)
### Main Libraries:
- [`rx.js`](libraries/main/rx.md)
- [`rx.aggregates.js`](libraries/main/rx.aggregates.md)
- [`rx.async.js`](libraries/main/rx.async.md)
- [`rx.binding.js`](libraries/main/rx.binding.md)
- [`rx.coincidence.js`](libraries/main/rx.coincidence.md)
- [`rx.experimental.js`](libraries/main/rx.experimental.md)
- [`rx.joinpatterns.js`](libraries/main/rx.joinpatterns.md)
- [`rx.testing.js`](libraries/main/rx.testing.md)
- [`rx.time.js`](libraries/main/rx.time.md)
- [`rx.virtualtime.js`](libraries/main/rx.virtualtime.md)
### Lite Libraries:
- [`rx.lite.js`](libraries/lite/rx.lite.md)
- [`rx.lite.extras.js`](libraries/lite/rx.lite.extras.md)
- [`rx.lite.aggregates.js`](libraries/lite/rx.lite.aggregates.md)
- [`rx.lite.async.js`](libraries/lite/rx.lite.async.md)
- [`rx.lite.coincidence.js`](libraries/lite/rx.lite.coincidence.md)
- [`rx.lite.experimental.js`](libraries/lite/rx.lite.experimental.md)
- [`rx.lite.joinpatterns.js`](libraries/lite/rx.lite.joinpatterns.md)
- [`rx.lite.testing.js`](libraries/lite/rx.lite.testing.md)
- [`rx.lite.time.js`](libraries/lite/rx.lite.time.md)
- [`rx.lite.virtualtime.js`](libraries/lite/rx.lite.virtualtime.md)
### Core Libraries:
- [`rx.core.js`](libraries/core/rx.core.md)
- [`rx.core.binding.js`](libraries/core/rx.core.binding.md)
- [`rx.core.testing.js`](libraries/core/rx.core.testing.md)
## How Do I? ##
There is a large surface area with the Reactive Extensions for JavaScript, so it might be hard to know where to start. This will serve as a guide to answer some of the more basic questions.
1. [How do I wrap an existing API?](howdoi/wrap.md)
2. [How do I integrate jQuery with RxJS?](howdoi/jquery.md)
3. [How do I integrate Angular.js with RxJS?](howdoi/angular.md)
4. [How do I create a simple event emitter?](howdoi/eventemitter.md)
## Mapping RxJS from Different Libraries ##
Converting your existing code from other libraries can be easy. Many of the concepts you already know from popular libraries such as [Bacon.js](https://github.com/baconjs/bacon.js) and [Async.js](https://github.com/caolan/async)
1. For Bacon.js Users
- [Why RxJS versus Bacon.js](mapping/bacon.js/whyrx.md)
- [Comparing RxJS and Bacon.js](mapping/bacon.js/comparing.md)
2. For Async.js Users
- [Why RxJS versus Async.js](mapping/async/whyrx.md)
- [Comparing RxJS and Async.js](mapping/async/comparing.md)
3. For Highland.js Users
- [Why RxJS versus Highland.js](mapping/highland/whyrx.md)
- [Comparing RxJS and Highland.js](mapping/highland/comparing.md)
## Reactive Extensions Class Library
This section contains the reference documentation for the Reactive Extensions class library.
### Helpers
- [`Rx.config`](api/config/readme.md)
- [`Rx.helpers`](api/helpers/readme.md)
### Core
- [`Rx.Observable`](api/core/observable.md)
- [`Rx.Observer`](api/core/observer.md)
- [`Rx.Notification`](api/core/notification.md)
### Subjects
- [`Rx.AsyncSubject`](api/subjects/asyncsubject.md)
- [`Rx.BehaviorSubject`](api/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](api/subjects/replaysubject.md)
- [`Rx.Subject`](api/subjects/subject.md)
### Schedulers
- [`Rx.HistoricalScheduler`](api/schedulers/historicalscheduler.md)
- [`Rx.Scheduler`](api/schedulers/scheduler.md)
- [`Rx.VirtualTimeScheduler`](api/schedulers/virtualtimescheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](api/disposables/compositedisposable.md)
- [`Rx.Disposable`](api/disposables/disposable.md)
- [`Rx.RefCountDisposable`](api/disposables/refcountdisposable.md)
- [`Rx.SerialDisposable`](api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](api/disposables/singleassignmentdisposable.md)
### Testing
- [`Rx.ReactiveTest`](api/testing/reactivetest.md)
- [`Rx.Recorded`](api/testing/recorded.md)
- [`Rx.Subscription`](api/testing/subscription.md)
- [`Rx.TestScheduler`](api/testing/testscheduler.md)
================================================
FILE: examples/alphabetinvasion/alphabetinvasion.html
================================================
Alphabet Invasion!
Alphabet Invasion!
SCORE:
0
LEVEL:
ENEMIES REMAINING:
HIGH SCORE
0
As the letters fall, type the letter that is lowest to the ground to keep your planet safe from these alphabetical invaders!
Score higher by zapping the invaders as early as possible.
Remember, these sneaky invaders are CaSe-SeNsItIvE!
================================================
FILE: examples/alphabetinvasion/alphabetinvasion.js
================================================
(function () {
// Non-standard custom operator
Rx.Observable.random = function (low, high, intervalLow, intervalHigh, howMany, scheduler) {
scheduler || (scheduler = Rx.Scheduler['default']);
if (howMany == null) { howMany = -1; }
if (intervalLow == null) { intervalLow = 1; }
if (intervalHigh == null) { intervalHigh = 1; }
return Rx.Observable.create(function (observer) {
var delta = high - low, intervalDelta = intervalHigh - intervalLow;
var iFunc = (intervalDelta === 0) ?
function () { return intervalLow; } :
function () { return Math.floor((Math.random() * intervalDelta) + intervalLow); };
return scheduler.scheduleRecursiveFuture(0, iFunc(), function (ticks, recurse) {
if (++ticks <= howMany) {
observer.onNext(Math.floor((Math.random() * delta) + low));
recurse(ticks, iFunc());
} else {
observer.onCompleted();
}
});
});
};
var GameState = {
playing: 'playing',
paused: 'paused',
stopped: 'stopped'
};
var AlphabetInvasion = (function () {
function AlphabetInvasion() {
this.enemies = [];
// get references to our needed DOM elements
this.modalBox = document.querySelector('#modalmessages');
this.message = document.querySelector('#message');
this.score = document.querySelector('#score');
this.playfield = document.querySelector('#playfield');
this.level = document.querySelector("#level");
this.remainingEnemies = document.querySelector("#remaining");
this.highScore = document.querySelector("#highscore");
}
var CURRENT_SPEED = 0;
var LAUNCH_RATE = 1;
var HIGH_SCORE_STORAGE_KEY = '_alphabet_attack_high_score_';
var playfieldheight = 0;
var lookup = "abcdefghijklmnopqrstuvwxyz";
var levels = {
"Level 1 - Rookies": [60, 1300],
"Level 2 - Tenderfoots": [55, 1200],
"Level 3 - Militia": [50, 1100],
"Level 4 - Privates": [50, 1000],
"Level 5 - Corporals": [45, 800],
"Level 6 - Sergeants": [40, 650],
"Level 7 - Master Sergeants": [35, 500],
"Level 8 - Lieutenants": [30, 450],
"Level 9 - Captains": [25, 400],
"Level 10 - Majors": [20, 400],
"Level 11 - Colonels": [15, 350],
"Level 12 - Generals": [11, 350],
"Level 13 - Special Forces": [9, 350],
"Level 14 - Black Ops": [7, 350],
"Level 15 - Ninjas": [5, 350]
};
AlphabetInvasion.prototype.run = function () {
this.resetGame();
this.keyboardObservable = Rx.Observable.fromEvent(document, 'keyup');
// If paused cause game to start
var self = this;
this.keyboardObservable.subscribe(function () {
if (self.gameState === GameState.paused) {
self.hideMessage();
self.playLevel();
}
});
if (window.localStorage) {
var hs = window.localStorage.getItem(HIGH_SCORE_STORAGE_KEY);
if (hs !== null) {
this.highScore.textContent = hs;
}
}
};
AlphabetInvasion.prototype.playLevel = function () {
if (this.generator) {
this.generator.dispose();
}
var title, found = false;
for (var level in levels) {
if (level.indexOf(this.currentLevel) !== -1) {
found = true;
}
if (found) {
title = level;
break;
}
}
var config = levels[level];
this.gameState = GameState.playing;
this.level.textContent = this.currentLevel;
this.showMessage(title);
// nested method to handle the actual gameplay loop
var self = this;
var play = function () {
self.hideMessage();
var enemiesThisLevel = self.currentLevel * 2 + 13;
self.remainingEnemies.textContent = enemiesThisLevel;
var capitalLetterProbability = 1 - ((self.currentLevel * 2.5) / 100);
var killed = 0;
var allEnemiesLaunched = false;
// Start the game loop, which updates the enemies.
self.gameloop = Rx.Observable.interval(config[CURRENT_SPEED]).subscribe(function () {
self.updatePlayfield();
});
// set another subscriber to the keyboardObservable
// which handles play input during each level
self.keyboard = self.keyboardObservable.subscribe(function (e) {
if (self.enemies.length === 0 && !allEnemiesLaunched) {
return;
}
if (self.enemies.length === 0 && allEnemiesLaunched) {
self.nextLevel();
return;
}
var key = e.shiftKey ? String.fromCharCode(e.keyCode) : String.fromCharCode(e.keyCode).toLowerCase();
console.log('key pressed: ' + key + ' enemy text: ' + self.enemies[0].textContent);
if (key === self.enemies[0].textContent) {
var enemy = self.enemies.shift();
self.killEnemy(enemy);
self.remainingEnemies.textContent = enemiesThisLevel - ++killed;
if (self.enemies.length === 0 && allEnemiesLaunched) {
self.nextLevel();
}
}
});
// Generate enemies for this Level.
// 10% chance for uppercase enemy
self.generator = Rx.Observable.random(0, 25, config[LAUNCH_RATE], config[LAUNCH_RATE], enemiesThisLevel).select(function (v) {
return Math.random() <= capitalLetterProbability ? lookup.charAt(v) : lookup.charAt(v).toUpperCase();
}).subscribe(function (v) {
self.launchNewEnemy(v);
}, function (e) {
throw e;
}, function () {
allEnemiesLaunched = true;
});
};
// This observable sets a delay for showing the level title,
// after which we call the nested play() method to start
// the level.
Rx.Observable.timer(2500).subscribe(function () { play(); });
};
AlphabetInvasion.prototype.nextLevel = function () {
if (this.currentLevel === 15) {
this.youWin();
}
this.gameState = GameState.stopped;
this.gameloop.dispose();
this.generator.dispose();
this.keyboard.dispose();
this.showMessage('Level ' + this.currentLevel + ' Complete');
this.currentLevel++;
var self = this;
Rx.Observable.timer(4000).subscribe(function () { self.playLevel(); });
};
AlphabetInvasion.prototype.youWin = function () {
if (this.gameState === GameState.stopped) {
return;
}
// change game state and dispose of our
// game loop observables
this.gameState = GameState.stopped;
this.gameloop.dispose();
this.generator.dispose();
this.keyboard.dispose();
this.showMessage("You win this time Earthling! We'll be back!");
// reset the game after 5.5 seconds
var self = this;
Rx.Observable.timer(5500).subscribe(function () {
self.resetGame();
});
};
AlphabetInvasion.prototype.youLose = function () {
if (this.gameState === GameState.stopped) {
return;
}
// change game state and dispose of our
// game loop observables
this.gameState = GameState.Stopped;
this.gameloop.dispose();
this.generator.dispose();
this.keyboard.dispose();
// adjust all enemies except the one that landed
// to look like :P
for (var i = 0, len = this.enemies.length; i < len; i++) {
var enemy = this.enemies[i];
if (enemy !== this.enemies[0]) {
enemy.textContent = ':P';
enemy.className += ' rotate';
enemy.style.fontSize = '72px';
}
}
this.showMessage("You Lose Earthling. Prepare to be alphabetized!");
// reset the game after 4.5 seconds
var self = this;
Rx.Observable.timer(5500).subscribe(function () {
self.resetGame();
});
};
AlphabetInvasion.prototype.killEnemy = function (enemy) {
// adjust the enemy visual
enemy.style.color = 'red';
enemy.style.fontSize = '48px';
enemy.textContent = '@';
// calculate a score
var v = enemy.offsetTop;
this.addToScore((this.playfield.clientHeight - v) * this.currentLevel);
// remove the enemy from the DOM after 750ms
var self = this;
Rx.Observable.timer(750).subscribe(function () {
self.playfield.removeChild(enemy);
});
};
// Updates positions of all enemies and calculates if an enemy has landed.
AlphabetInvasion.prototype.updatePlayfield = function () {
// adjusting enemy speed based on playfield height
playfieldheight = this.playfield.clientTop + this.playfield.clientHeight;
var factor = playfieldheight / 200;
var self = this;
Rx.Observable.fromArray(this.enemies).subscribe(function (enemy) {
var newPos = enemy.offsetTop + factor;
enemy.style.top = newPos + 'px';
if (newPos >= playfieldheight + 44) {
self.youLose();
}
});
};
AlphabetInvasion.prototype.launchNewEnemy = function (v) {
//randomize a color, not too dark
var r = Math.floor(Math.random() * 100 + 155)
, g = Math.floor(Math.random() * 100 + 155)
, b = Math.floor(Math.random() * 100 + 155);
// build the enemy and set it's initial position
var enemy = document.createElement('div');
enemy.style.color = 'rgb(' + r + ',' + g + ',' + b + ')';
enemy.style.position = 'absolute';
enemy.style.top = this.playfield.offsetTop + 'px';
enemy.style.left = (Math.random() * (this.playfield.clientWidth - 25)) + 'px';
enemy.className = 'enemy';
enemy.textContent = v;
// update the tracking queue and add the enemy to the DOM
this.enemies.push(enemy);
this.playfield.appendChild(enemy);
};
AlphabetInvasion.prototype.addToScore = function (amount) {
var newScore = parseInt(this.score.textContent) + amount;
this.score.textContent = newScore;
if (newScore > parseInt(this.highScore.textContent)) {
this.highScore.textContent = newScore;
if (window.localStorage){
window.localStorage.setItem(HIGH_SCORE_STORAGE_KEY, newScore);
}
}
};
AlphabetInvasion.prototype.resetGame = function () {
this.gameState = GameState.paused;
this.showMessage('');
this.currentLevel = 1;
this.score.textContent = '0';
this.level.textContent = '1';
this.remainingEnemies.textContent = '-';
this.clearPlayfield();
if (this.windowHeight) this.windowHeight.dispose();
if (this.generator) this.generator.dispose();
if (this.matcher) this.matcher.dispose();
if (this.gameloop) this.gameloop.dispose();
if (this.keyboard) this.keyboard.dispose();
this.showMessage('PRESS ANY KEY TO START');
};
AlphabetInvasion.prototype.clearPlayfield = function () {
for (var i = 0, len = this.enemies.length; i < len; i++) {
this.playfield.removeChild(this.enemies[i]);
}
this.enemies = [];
};
// Displays a model message one letter at a time.
AlphabetInvasion.prototype.showMessage = function (msg) {
if (msg && msg.length === 0) {
this.message.text = '';
return;
}
this.modalBox.style.opacity = 1;
var self = this;
for (var i = 0, len = msg.length; i < len; i++) {
(function (i) {
Rx.Observable.just(i).delay(30 * i).subscribe(function (x) {
self.message.textContent = msg.substring(0, x + 1);
});
})(i);
}
};
AlphabetInvasion.prototype.hideMessage = function () {
this.modalBox.style.opacity = 0;
};
return AlphabetInvasion;
})();
var game = new AlphabetInvasion();
game.run();
})();
================================================
FILE: examples/alphabetinvasion/main.css
================================================
html{
margin:0px;
padding:0px;
}
body{
background: black;
font-family: Consolas, courier;
color: WhiteSmoke;
margin:0px;
padding:0px;
overflow:hidden;
}
#title {
text-align:center;
font-size:38px;
color: Yellow;
}
#updatefield {
font-size: 24px;
display: -ms-flexbox;
display: -webkit-box;
display: -moz-box;
display: box;
}
.infotitle {
padding-left: 1.5em;
color: LightGreen;
}
.info{
padding-left: .5em;
width:4em;
}
.enemy{
position: absolute;
margin: 0px;
font-size: 30px;
-webkit-transition: font-size 1s linear;
-moz-transition: font-size 1s linear;
-ms-transition: font-size 1s linear;
transition: font-size 1s linear;
}
#playfield{
height: 500px;
border: solid 1px #a8a8a8;
border-bottom: solid 5px Green;
background-image: linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%);
background-image: -o-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%);
background-image: -ms-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%);
background-image: -moz-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%);
background-image: -webkit-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%);
}
.rotate{
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
/*rotate(90deg); */
}
.instructions{
text-align:center;
font-size: 18px;
}
#modalmessages{
opacity: 0;
height: 100%;
width: 100%;
background: #333377;
/* flexbox */
display: -ms-flexbox;
-ms-flex-pack: center;
-ms-flex-align:center;
/* Box display */
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack:center;
-webkit-box-align: center;
-moz-box-align: center;
box-align: center;
/* Transition */
-ms-transition: opacity .5s linear;
-webkit-transition: opacity .5s linear;
-moz-transition: opacity .5s linear;
transition: opacity .5s linear;
}
#message{
font-size: 45px;
}
================================================
FILE: examples/alphabetinvasion/readme.md
================================================
================================================
FILE: examples/animationtest/index.html
================================================
RxJS Animation Test
'
, trigger: 'hover focus'
, title: ''
, delay: 0
, html: false
, container: false
}
/* TOOLTIP NO CONFLICT
* =================== */
$.fn.tooltip.noConflict = function () {
$.fn.tooltip = old
return this
}
}(window.jQuery);
/* ===========================================================
* bootstrap-popover.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#popovers
* ===========================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* POPOVER PUBLIC CLASS DEFINITION
* =============================== */
var Popover = function (element, options) {
this.init('popover', element, options)
}
/* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
========================================== */
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
constructor: Popover
, setContent: function () {
var $tip = this.tip()
, title = this.getTitle()
, content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
$tip.removeClass('fade top bottom left right in')
}
, hasContent: function () {
return this.getTitle() || this.getContent()
}
, getContent: function () {
var content
, $e = this.$element
, o = this.options
content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
|| $e.attr('data-content')
return content
}
, tip: function () {
if (!this.$tip) {
this.$tip = $(this.options.template)
}
return this.$tip
}
, destroy: function () {
this.hide().$element.off('.' + this.type).removeData(this.type)
}
})
/* POPOVER PLUGIN DEFINITION
* ======================= */
var old = $.fn.popover
$.fn.popover = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('popover')
, options = typeof option == 'object' && option
if (!data) $this.data('popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.popover.Constructor = Popover
$.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
placement: 'right'
, trigger: 'click'
, content: ''
, template: '
'
})
/* POPOVER NO CONFLICT
* =================== */
$.fn.popover.noConflict = function () {
$.fn.popover = old
return this
}
}(window.jQuery);
/* =============================================================
* bootstrap-scrollspy.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#scrollspy
* =============================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* SCROLLSPY CLASS DEFINITION
* ========================== */
function ScrollSpy(element, options) {
var process = $.proxy(this.process, this)
, $element = $(element).is('body') ? $(window) : $(element)
, href
this.options = $.extend({}, $.fn.scrollspy.defaults, options)
this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
this.selector = (this.options.target
|| ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|| '') + ' .nav li > a'
this.$body = $('body')
this.refresh()
this.process()
}
ScrollSpy.prototype = {
constructor: ScrollSpy
, refresh: function () {
var self = this
, $targets
this.offsets = $([])
this.targets = $([])
$targets = this.$body
.find(this.selector)
.map(function () {
var $el = $(this)
, href = $el.data('target') || $el.attr('href')
, $href = /^#\w/.test(href) && $(href)
return ( $href
&& $href.length
&& [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
})
.sort(function (a, b) { return a[0] - b[0] })
.each(function () {
self.offsets.push(this[0])
self.targets.push(this[1])
})
}
, process: function () {
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
, scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
, maxScroll = scrollHeight - this.$scrollElement.height()
, offsets = this.offsets
, targets = this.targets
, activeTarget = this.activeTarget
, i
if (scrollTop >= maxScroll) {
return activeTarget != (i = targets.last()[0])
&& this.activate ( i )
}
for (i = offsets.length; i--;) {
activeTarget != targets[i]
&& scrollTop >= offsets[i]
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
&& this.activate( targets[i] )
}
}
, activate: function (target) {
var active
, selector
this.activeTarget = target
$(this.selector)
.parent('.active')
.removeClass('active')
selector = this.selector
+ '[data-target="' + target + '"],'
+ this.selector + '[href="' + target + '"]'
active = $(selector)
.parent('li')
.addClass('active')
if (active.parent('.dropdown-menu').length) {
active = active.closest('li.dropdown').addClass('active')
}
active.trigger('activate')
}
}
/* SCROLLSPY PLUGIN DEFINITION
* =========================== */
var old = $.fn.scrollspy
$.fn.scrollspy = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('scrollspy')
, options = typeof option == 'object' && option
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
$.fn.scrollspy.defaults = {
offset: 10
}
/* SCROLLSPY NO CONFLICT
* ===================== */
$.fn.scrollspy.noConflict = function () {
$.fn.scrollspy = old
return this
}
/* SCROLLSPY DATA-API
* ================== */
$(window).on('load', function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);/* ========================================================
* bootstrap-tab.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#tabs
* ========================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* TAB CLASS DEFINITION
* ==================== */
var Tab = function (element) {
this.element = $(element)
}
Tab.prototype = {
constructor: Tab
, show: function () {
var $this = this.element
, $ul = $this.closest('ul:not(.dropdown-menu)')
, selector = $this.attr('data-target')
, previous
, $target
, e
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
if ( $this.parent('li').hasClass('active') ) return
previous = $ul.find('.active:last a')[0]
e = $.Event('show', {
relatedTarget: previous
})
$this.trigger(e)
if (e.isDefaultPrevented()) return
$target = $(selector)
this.activate($this.parent('li'), $ul)
this.activate($target, $target.parent(), function () {
$this.trigger({
type: 'shown'
, relatedTarget: previous
})
})
}
, activate: function ( element, container, callback) {
var $active = container.find('> .active')
, transition = callback
&& $.support.transition
&& $active.hasClass('fade')
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
element.addClass('active')
if (transition) {
element[0].offsetWidth // reflow for transition
element.addClass('in')
} else {
element.removeClass('fade')
}
if ( element.parent('.dropdown-menu') ) {
element.closest('li.dropdown').addClass('active')
}
callback && callback()
}
transition ?
$active.one($.support.transition.end, next) :
next()
$active.removeClass('in')
}
}
/* TAB PLUGIN DEFINITION
* ===================== */
var old = $.fn.tab
$.fn.tab = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('tab')
if (!data) $this.data('tab', (data = new Tab(this)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tab.Constructor = Tab
/* TAB NO CONFLICT
* =============== */
$.fn.tab.noConflict = function () {
$.fn.tab = old
return this
}
/* TAB DATA-API
* ============ */
$(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
e.preventDefault()
$(this).tab('show')
})
}(window.jQuery);/* =============================================================
* bootstrap-typeahead.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#typeahead
* =============================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function($){
"use strict"; // jshint ;_;
/* TYPEAHEAD PUBLIC CLASS DEFINITION
* ================================= */
var Typeahead = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, $.fn.typeahead.defaults, options)
this.matcher = this.options.matcher || this.matcher
this.sorter = this.options.sorter || this.sorter
this.highlighter = this.options.highlighter || this.highlighter
this.updater = this.options.updater || this.updater
this.source = this.options.source
this.$menu = $(this.options.menu)
this.shown = false
this.listen()
}
Typeahead.prototype = {
constructor: Typeahead
, select: function () {
var val = this.$menu.find('.active').attr('data-value')
this.$element
.val(this.updater(val))
.change()
return this.hide()
}
, updater: function (item) {
return item
}
, show: function () {
var pos = $.extend({}, this.$element.position(), {
height: this.$element[0].offsetHeight
})
this.$menu
.insertAfter(this.$element)
.css({
top: pos.top + pos.height
, left: pos.left
})
.show()
this.shown = true
return this
}
, hide: function () {
this.$menu.hide()
this.shown = false
return this
}
, lookup: function (event) {
var items
this.query = this.$element.val()
if (!this.query || this.query.length < this.options.minLength) {
return this.shown ? this.hide() : this
}
items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
return items ? this.process(items) : this
}
, process: function (items) {
var that = this
items = $.grep(items, function (item) {
return that.matcher(item)
})
items = this.sorter(items)
if (!items.length) {
return this.shown ? this.hide() : this
}
return this.render(items.slice(0, this.options.items)).show()
}
, matcher: function (item) {
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
}
, sorter: function (items) {
var beginswith = []
, caseSensitive = []
, caseInsensitive = []
, item
while (item = items.shift()) {
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
else if (~item.indexOf(this.query)) caseSensitive.push(item)
else caseInsensitive.push(item)
}
return beginswith.concat(caseSensitive, caseInsensitive)
}
, highlighter: function (item) {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '' + match + ''
})
}
, render: function (items) {
var that = this
items = $(items).map(function (i, item) {
i = $(that.options.item).attr('data-value', item)
i.find('a').html(that.highlighter(item))
return i[0]
})
items.first().addClass('active')
this.$menu.html(items)
return this
}
, next: function (event) {
var active = this.$menu.find('.active').removeClass('active')
, next = active.next()
if (!next.length) {
next = $(this.$menu.find('li')[0])
}
next.addClass('active')
}
, prev: function (event) {
var active = this.$menu.find('.active').removeClass('active')
, prev = active.prev()
if (!prev.length) {
prev = this.$menu.find('li').last()
}
prev.addClass('active')
}
, listen: function () {
this.$element
.on('focus', $.proxy(this.focus, this))
.on('blur', $.proxy(this.blur, this))
.on('keypress', $.proxy(this.keypress, this))
.on('keyup', $.proxy(this.keyup, this))
if (this.eventSupported('keydown')) {
this.$element.on('keydown', $.proxy(this.keydown, this))
}
this.$menu
.on('click', $.proxy(this.click, this))
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
}
, eventSupported: function(eventName) {
var isSupported = eventName in this.$element
if (!isSupported) {
this.$element.setAttribute(eventName, 'return;')
isSupported = typeof this.$element[eventName] === 'function'
}
return isSupported
}
, move: function (e) {
if (!this.shown) return
switch(e.keyCode) {
case 9: // tab
case 13: // enter
case 27: // escape
e.preventDefault()
break
case 38: // up arrow
e.preventDefault()
this.prev()
break
case 40: // down arrow
e.preventDefault()
this.next()
break
}
e.stopPropagation()
}
, keydown: function (e) {
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
this.move(e)
}
, keypress: function (e) {
if (this.suppressKeyPressRepeat) return
this.move(e)
}
, keyup: function (e) {
switch(e.keyCode) {
case 40: // down arrow
case 38: // up arrow
case 16: // shift
case 17: // ctrl
case 18: // alt
break
case 9: // tab
case 13: // enter
if (!this.shown) return
this.select()
break
case 27: // escape
if (!this.shown) return
this.hide()
break
default:
this.lookup()
}
e.stopPropagation()
e.preventDefault()
}
, focus: function (e) {
this.focused = true
}
, blur: function (e) {
this.focused = false
if (!this.mousedover && this.shown) this.hide()
}
, click: function (e) {
e.stopPropagation()
e.preventDefault()
this.select()
this.$element.focus()
}
, mouseenter: function (e) {
this.mousedover = true
this.$menu.find('.active').removeClass('active')
$(e.currentTarget).addClass('active')
}
, mouseleave: function (e) {
this.mousedover = false
if (!this.focused && this.shown) this.hide()
}
}
/* TYPEAHEAD PLUGIN DEFINITION
* =========================== */
var old = $.fn.typeahead
$.fn.typeahead = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('typeahead')
, options = typeof option == 'object' && option
if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.typeahead.defaults = {
source: []
, items: 8
, menu: '
'
, item: '
'
, minLength: 1
}
$.fn.typeahead.Constructor = Typeahead
/* TYPEAHEAD NO CONFLICT
* =================== */
$.fn.typeahead.noConflict = function () {
$.fn.typeahead = old
return this
}
/* TYPEAHEAD DATA-API
* ================== */
$(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
var $this = $(this)
if ($this.data('typeahead')) return
$this.typeahead($this.data())
})
}(window.jQuery);
/* ==========================================================
* bootstrap-affix.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#affix
* ==========================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* AFFIX CLASS DEFINITION
* ====================== */
var Affix = function (element, options) {
this.options = $.extend({}, $.fn.affix.defaults, options)
this.$window = $(window)
.on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
.on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
this.$element = $(element)
this.checkPosition()
}
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
, scrollTop = this.$window.scrollTop()
, position = this.$element.offset()
, offset = this.options.offset
, offsetBottom = offset.bottom
, offsetTop = offset.top
, reset = 'affix affix-top affix-bottom'
, affix
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top()
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
'bottom' : offsetTop != null && scrollTop <= offsetTop ?
'top' : false
if (this.affixed === affix) return
this.affixed = affix
this.unpin = affix == 'bottom' ? position.top - scrollTop : null
this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
}
/* AFFIX PLUGIN DEFINITION
* ======================= */
var old = $.fn.affix
$.fn.affix = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('affix')
, options = typeof option == 'object' && option
if (!data) $this.data('affix', (data = new Affix(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.affix.Constructor = Affix
$.fn.affix.defaults = {
offset: 0
}
/* AFFIX NO CONFLICT
* ================= */
$.fn.affix.noConflict = function () {
$.fn.affix = old
return this
}
/* AFFIX DATA-API
* ============== */
$(window).on('load', function () {
$('[data-spy="affix"]').each(function () {
var $spy = $(this)
, data = $spy.data()
data.offset = data.offset || {}
data.offsetBottom && (data.offset.bottom = data.offsetBottom)
data.offsetTop && (data.offset.top = data.offsetTop)
$spy.affix(data)
})
})
}(window.jQuery);
================================================
FILE: examples/assets/d3/LICENSE
================================================
Copyright (c) 2010-2014, Michael Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name Michael Bostock may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: examples/assets/d3/d3.js
================================================
!function() {
var d3 = {
version: "3.4.11"
};
if (!Date.now) Date.now = function() {
return +new Date();
};
var d3_arraySlice = [].slice, d3_array = function(list) {
return d3_arraySlice.call(list);
};
var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window;
try {
d3_array(d3_documentElement.childNodes)[0].nodeType;
} catch (e) {
d3_array = function(list) {
var i = list.length, array = new Array(i);
while (i--) array[i] = list[i];
return array;
};
}
try {
d3_document.createElement("div").style.setProperty("opacity", 0, "");
} catch (error) {
var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
d3_element_prototype.setAttribute = function(name, value) {
d3_element_setAttribute.call(this, name, value + "");
};
d3_element_prototype.setAttributeNS = function(space, local, value) {
d3_element_setAttributeNS.call(this, space, local, value + "");
};
d3_style_prototype.setProperty = function(name, value, priority) {
d3_style_setProperty.call(this, name, value + "", priority);
};
}
d3.ascending = d3_ascending;
function d3_ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
d3.descending = function(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
d3.min = function(array, f) {
var i = -1, n = array.length, a, b;
if (arguments.length === 1) {
while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined;
while (++i < n) if ((b = array[i]) != null && a > b) a = b;
} else {
while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
}
return a;
};
d3.max = function(array, f) {
var i = -1, n = array.length, a, b;
if (arguments.length === 1) {
while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined;
while (++i < n) if ((b = array[i]) != null && b > a) a = b;
} else {
while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
}
return a;
};
d3.extent = function(array, f) {
var i = -1, n = array.length, a, b, c;
if (arguments.length === 1) {
while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined;
while (++i < n) if ((b = array[i]) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
} else {
while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
}
return [ a, c ];
};
d3.sum = function(array, f) {
var s = 0, n = array.length, a, i = -1;
if (arguments.length === 1) {
while (++i < n) if (!isNaN(a = +array[i])) s += a;
} else {
while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
}
return s;
};
function d3_number(x) {
return x != null && !isNaN(x);
}
d3.mean = function(array, f) {
var s = 0, n = array.length, a, i = -1, j = n;
if (arguments.length === 1) {
while (++i < n) if (d3_number(a = array[i])) s += a; else --j;
} else {
while (++i < n) if (d3_number(a = f.call(array, array[i], i))) s += a; else --j;
}
return j ? s / j : undefined;
};
d3.quantile = function(values, p) {
var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
return e ? v + e * (values[h] - v) : v;
};
d3.median = function(array, f) {
if (arguments.length > 1) array = array.map(f);
array = array.filter(d3_number);
return array.length ? d3.quantile(array.sort(d3_ascending), .5) : undefined;
};
function d3_bisector(compare) {
return {
left: function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
},
right: function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1;
}
return lo;
}
};
}
var d3_bisect = d3_bisector(d3_ascending);
d3.bisectLeft = d3_bisect.left;
d3.bisect = d3.bisectRight = d3_bisect.right;
d3.bisector = function(f) {
return d3_bisector(f.length === 1 ? function(d, x) {
return d3_ascending(f(d), x);
} : f);
};
d3.shuffle = function(array) {
var m = array.length, t, i;
while (m) {
i = Math.random() * m-- | 0;
t = array[m], array[m] = array[i], array[i] = t;
}
return array;
};
d3.permute = function(array, indexes) {
var i = indexes.length, permutes = new Array(i);
while (i--) permutes[i] = array[indexes[i]];
return permutes;
};
d3.pairs = function(array) {
var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
return pairs;
};
d3.zip = function() {
if (!(n = arguments.length)) return [];
for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {
zip[j] = arguments[j][i];
}
}
return zips;
};
function d3_zipLength(d) {
return d.length;
}
d3.transpose = function(matrix) {
return d3.zip.apply(d3, matrix);
};
d3.keys = function(map) {
var keys = [];
for (var key in map) keys.push(key);
return keys;
};
d3.values = function(map) {
var values = [];
for (var key in map) values.push(map[key]);
return values;
};
d3.entries = function(map) {
var entries = [];
for (var key in map) entries.push({
key: key,
value: map[key]
});
return entries;
};
d3.merge = function(arrays) {
var n = arrays.length, m, i = -1, j = 0, merged, array;
while (++i < n) j += arrays[i].length;
merged = new Array(j);
while (--n >= 0) {
array = arrays[n];
m = array.length;
while (--m >= 0) {
merged[--j] = array[m];
}
}
return merged;
};
var abs = Math.abs;
d3.range = function(start, stop, step) {
if (arguments.length < 3) {
step = 1;
if (arguments.length < 2) {
stop = start;
start = 0;
}
}
if ((stop - start) / step === Infinity) throw new Error("infinite range");
var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;
start *= k, stop *= k, step *= k;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);
return range;
};
function d3_range_integerScale(x) {
var k = 1;
while (x * k % 1) k *= 10;
return k;
}
function d3_class(ctor, properties) {
try {
for (var key in properties) {
Object.defineProperty(ctor.prototype, key, {
value: properties[key],
enumerable: false
});
}
} catch (e) {
ctor.prototype = properties;
}
}
d3.map = function(object) {
var map = new d3_Map();
if (object instanceof d3_Map) object.forEach(function(key, value) {
map.set(key, value);
}); else for (var key in object) map.set(key, object[key]);
return map;
};
function d3_Map() {}
d3_class(d3_Map, {
has: d3_map_has,
get: function(key) {
return this[d3_map_prefix + key];
},
set: function(key, value) {
return this[d3_map_prefix + key] = value;
},
remove: d3_map_remove,
keys: d3_map_keys,
values: function() {
var values = [];
this.forEach(function(key, value) {
values.push(value);
});
return values;
},
entries: function() {
var entries = [];
this.forEach(function(key, value) {
entries.push({
key: key,
value: value
});
});
return entries;
},
size: d3_map_size,
empty: d3_map_empty,
forEach: function(f) {
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.substring(1), this[key]);
}
});
var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
function d3_map_has(key) {
return d3_map_prefix + key in this;
}
function d3_map_remove(key) {
key = d3_map_prefix + key;
return key in this && delete this[key];
}
function d3_map_keys() {
var keys = [];
this.forEach(function(key) {
keys.push(key);
});
return keys;
}
function d3_map_size() {
var size = 0;
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size;
return size;
}
function d3_map_empty() {
for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false;
return true;
}
d3.nest = function() {
var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
function map(mapType, array, depth) {
if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;
var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;
while (++i < n) {
if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
values.push(object);
} else {
valuesByKey.set(keyValue, [ object ]);
}
}
if (mapType) {
object = mapType();
setter = function(keyValue, values) {
object.set(keyValue, map(mapType, values, depth));
};
} else {
object = {};
setter = function(keyValue, values) {
object[keyValue] = map(mapType, values, depth);
};
}
valuesByKey.forEach(setter);
return object;
}
function entries(map, depth) {
if (depth >= keys.length) return map;
var array = [], sortKey = sortKeys[depth++];
map.forEach(function(key, keyMap) {
array.push({
key: key,
values: entries(keyMap, depth)
});
});
return sortKey ? array.sort(function(a, b) {
return sortKey(a.key, b.key);
}) : array;
}
nest.map = function(array, mapType) {
return map(mapType, array, 0);
};
nest.entries = function(array) {
return entries(map(d3.map, array, 0), 0);
};
nest.key = function(d) {
keys.push(d);
return nest;
};
nest.sortKeys = function(order) {
sortKeys[keys.length - 1] = order;
return nest;
};
nest.sortValues = function(order) {
sortValues = order;
return nest;
};
nest.rollup = function(f) {
rollup = f;
return nest;
};
return nest;
};
d3.set = function(array) {
var set = new d3_Set();
if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
return set;
};
function d3_Set() {}
d3_class(d3_Set, {
has: d3_map_has,
add: function(value) {
this[d3_map_prefix + value] = true;
return value;
},
remove: function(value) {
value = d3_map_prefix + value;
return value in this && delete this[value];
},
values: d3_map_keys,
size: d3_map_size,
empty: d3_map_empty,
forEach: function(f) {
for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.substring(1));
}
});
d3.behavior = {};
d3.rebind = function(target, source) {
var i = 1, n = arguments.length, method;
while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
return target;
};
function d3_rebind(target, source, method) {
return function() {
var value = method.apply(source, arguments);
return value === source ? target : value;
};
}
function d3_vendorSymbol(object, name) {
if (name in object) return name;
name = name.charAt(0).toUpperCase() + name.substring(1);
for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {
var prefixName = d3_vendorPrefixes[i] + name;
if (prefixName in object) return prefixName;
}
}
var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ];
function d3_noop() {}
d3.dispatch = function() {
var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
return dispatch;
};
function d3_dispatch() {}
d3_dispatch.prototype.on = function(type, listener) {
var i = type.indexOf("."), name = "";
if (i >= 0) {
name = type.substring(i + 1);
type = type.substring(0, i);
}
if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);
if (arguments.length === 2) {
if (listener == null) for (type in this) {
if (this.hasOwnProperty(type)) this[type].on(name, null);
}
return this;
}
};
function d3_dispatch_event(dispatch) {
var listeners = [], listenerByName = new d3_Map();
function event() {
var z = listeners, i = -1, n = z.length, l;
while (++i < n) if (l = z[i].on) l.apply(this, arguments);
return dispatch;
}
event.on = function(name, listener) {
var l = listenerByName.get(name), i;
if (arguments.length < 2) return l && l.on;
if (l) {
l.on = null;
listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
listenerByName.remove(name);
}
if (listener) listeners.push(listenerByName.set(name, {
on: listener
}));
return dispatch;
};
return event;
}
d3.event = null;
function d3_eventPreventDefault() {
d3.event.preventDefault();
}
function d3_eventSource() {
var e = d3.event, s;
while (s = e.sourceEvent) e = s;
return e;
}
function d3_eventDispatch(target) {
var dispatch = new d3_dispatch(), i = 0, n = arguments.length;
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
dispatch.of = function(thiz, argumentz) {
return function(e1) {
try {
var e0 = e1.sourceEvent = d3.event;
e1.target = target;
d3.event = e1;
dispatch[e1.type].apply(thiz, argumentz);
} finally {
d3.event = e0;
}
};
};
return dispatch;
}
d3.requote = function(s) {
return s.replace(d3_requote_re, "\\$&");
};
var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
var d3_subclass = {}.__proto__ ? function(object, prototype) {
object.__proto__ = prototype;
} : function(object, prototype) {
for (var property in prototype) object[property] = prototype[property];
};
function d3_selection(groups) {
d3_subclass(groups, d3_selectionPrototype);
return groups;
}
var d3_select = function(s, n) {
return n.querySelector(s);
}, d3_selectAll = function(s, n) {
return n.querySelectorAll(s);
}, d3_selectMatcher = d3_documentElement.matches || d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) {
return d3_selectMatcher.call(n, s);
};
if (typeof Sizzle === "function") {
d3_select = function(s, n) {
return Sizzle(s, n)[0] || null;
};
d3_selectAll = Sizzle;
d3_selectMatches = Sizzle.matchesSelector;
}
d3.selection = function() {
return d3_selectionRoot;
};
var d3_selectionPrototype = d3.selection.prototype = [];
d3_selectionPrototype.select = function(selector) {
var subgroups = [], subgroup, subnode, group, node;
selector = d3_selection_selector(selector);
for (var j = -1, m = this.length; ++j < m; ) {
subgroups.push(subgroup = []);
subgroup.parentNode = (group = this[j]).parentNode;
for (var i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) {
subgroup.push(subnode = selector.call(node, node.__data__, i, j));
if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
} else {
subgroup.push(null);
}
}
}
return d3_selection(subgroups);
};
function d3_selection_selector(selector) {
return typeof selector === "function" ? selector : function() {
return d3_select(selector, this);
};
}
d3_selectionPrototype.selectAll = function(selector) {
var subgroups = [], subgroup, node;
selector = d3_selection_selectorAll(selector);
for (var j = -1, m = this.length; ++j < m; ) {
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) {
subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));
subgroup.parentNode = node;
}
}
}
return d3_selection(subgroups);
};
function d3_selection_selectorAll(selector) {
return typeof selector === "function" ? selector : function() {
return d3_selectAll(selector, this);
};
}
var d3_nsPrefix = {
svg: "http://www.w3.org/2000/svg",
xhtml: "http://www.w3.org/1999/xhtml",
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
};
d3.ns = {
prefix: d3_nsPrefix,
qualify: function(name) {
var i = name.indexOf(":"), prefix = name;
if (i >= 0) {
prefix = name.substring(0, i);
name = name.substring(i + 1);
}
return d3_nsPrefix.hasOwnProperty(prefix) ? {
space: d3_nsPrefix[prefix],
local: name
} : name;
}
};
d3_selectionPrototype.attr = function(name, value) {
if (arguments.length < 2) {
if (typeof name === "string") {
var node = this.node();
name = d3.ns.qualify(name);
return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);
}
for (value in name) this.each(d3_selection_attr(value, name[value]));
return this;
}
return this.each(d3_selection_attr(name, value));
};
function d3_selection_attr(name, value) {
name = d3.ns.qualify(name);
function attrNull() {
this.removeAttribute(name);
}
function attrNullNS() {
this.removeAttributeNS(name.space, name.local);
}
function attrConstant() {
this.setAttribute(name, value);
}
function attrConstantNS() {
this.setAttributeNS(name.space, name.local, value);
}
function attrFunction() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttribute(name); else this.setAttribute(name, x);
}
function attrFunctionNS() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);
}
return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;
}
function d3_collapse(s) {
return s.trim().replace(/\s+/g, " ");
}
d3_selectionPrototype.classed = function(name, value) {
if (arguments.length < 2) {
if (typeof name === "string") {
var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;
if (value = node.classList) {
while (++i < n) if (!value.contains(name[i])) return false;
} else {
value = node.getAttribute("class");
while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;
}
return true;
}
for (value in name) this.each(d3_selection_classed(value, name[value]));
return this;
}
return this.each(d3_selection_classed(name, value));
};
function d3_selection_classedRe(name) {
return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g");
}
function d3_selection_classes(name) {
return (name + "").trim().split(/^|\s+/);
}
function d3_selection_classed(name, value) {
name = d3_selection_classes(name).map(d3_selection_classedName);
var n = name.length;
function classedConstant() {
var i = -1;
while (++i < n) name[i](this, value);
}
function classedFunction() {
var i = -1, x = value.apply(this, arguments);
while (++i < n) name[i](this, x);
}
return typeof value === "function" ? classedFunction : classedConstant;
}
function d3_selection_classedName(name) {
var re = d3_selection_classedRe(name);
return function(node, value) {
if (c = node.classList) return value ? c.add(name) : c.remove(name);
var c = node.getAttribute("class") || "";
if (value) {
re.lastIndex = 0;
if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name));
} else {
node.setAttribute("class", d3_collapse(c.replace(re, " ")));
}
};
}
d3_selectionPrototype.style = function(name, value, priority) {
var n = arguments.length;
if (n < 3) {
if (typeof name !== "string") {
if (n < 2) value = "";
for (priority in name) this.each(d3_selection_style(priority, name[priority], value));
return this;
}
if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name);
priority = "";
}
return this.each(d3_selection_style(name, value, priority));
};
function d3_selection_style(name, value, priority) {
function styleNull() {
this.style.removeProperty(name);
}
function styleConstant() {
this.style.setProperty(name, value, priority);
}
function styleFunction() {
var x = value.apply(this, arguments);
if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority);
}
return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant;
}
d3_selectionPrototype.property = function(name, value) {
if (arguments.length < 2) {
if (typeof name === "string") return this.node()[name];
for (value in name) this.each(d3_selection_property(value, name[value]));
return this;
}
return this.each(d3_selection_property(name, value));
};
function d3_selection_property(name, value) {
function propertyNull() {
delete this[name];
}
function propertyConstant() {
this[name] = value;
}
function propertyFunction() {
var x = value.apply(this, arguments);
if (x == null) delete this[name]; else this[name] = x;
}
return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant;
}
d3_selectionPrototype.text = function(value) {
return arguments.length ? this.each(typeof value === "function" ? function() {
var v = value.apply(this, arguments);
this.textContent = v == null ? "" : v;
} : value == null ? function() {
this.textContent = "";
} : function() {
this.textContent = value;
}) : this.node().textContent;
};
d3_selectionPrototype.html = function(value) {
return arguments.length ? this.each(typeof value === "function" ? function() {
var v = value.apply(this, arguments);
this.innerHTML = v == null ? "" : v;
} : value == null ? function() {
this.innerHTML = "";
} : function() {
this.innerHTML = value;
}) : this.node().innerHTML;
};
d3_selectionPrototype.append = function(name) {
name = d3_selection_creator(name);
return this.select(function() {
return this.appendChild(name.apply(this, arguments));
});
};
function d3_selection_creator(name) {
return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() {
return this.ownerDocument.createElementNS(name.space, name.local);
} : function() {
return this.ownerDocument.createElementNS(this.namespaceURI, name);
};
}
d3_selectionPrototype.insert = function(name, before) {
name = d3_selection_creator(name);
before = d3_selection_selector(before);
return this.select(function() {
return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
});
};
d3_selectionPrototype.remove = function() {
return this.each(function() {
var parent = this.parentNode;
if (parent) parent.removeChild(this);
});
};
d3_selectionPrototype.data = function(value, key) {
var i = -1, n = this.length, group, node;
if (!arguments.length) {
value = new Array(n = (group = this[0]).length);
while (++i < n) {
if (node = group[i]) {
value[i] = node.__data__;
}
}
return value;
}
function bind(group, groupData) {
var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;
if (key) {
var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue;
for (i = -1; ++i < n; ) {
keyValue = key.call(node = group[i], node.__data__, i);
if (nodeByKeyValue.has(keyValue)) {
exitNodes[i] = node;
} else {
nodeByKeyValue.set(keyValue, node);
}
keyValues.push(keyValue);
}
for (i = -1; ++i < m; ) {
keyValue = key.call(groupData, nodeData = groupData[i], i);
if (node = nodeByKeyValue.get(keyValue)) {
updateNodes[i] = node;
node.__data__ = nodeData;
} else if (!dataByKeyValue.has(keyValue)) {
enterNodes[i] = d3_selection_dataNode(nodeData);
}
dataByKeyValue.set(keyValue, nodeData);
nodeByKeyValue.remove(keyValue);
}
for (i = -1; ++i < n; ) {
if (nodeByKeyValue.has(keyValues[i])) {
exitNodes[i] = group[i];
}
}
} else {
for (i = -1; ++i < n0; ) {
node = group[i];
nodeData = groupData[i];
if (node) {
node.__data__ = nodeData;
updateNodes[i] = node;
} else {
enterNodes[i] = d3_selection_dataNode(nodeData);
}
}
for (;i < m; ++i) {
enterNodes[i] = d3_selection_dataNode(groupData[i]);
}
for (;i < n; ++i) {
exitNodes[i] = group[i];
}
}
enterNodes.update = updateNodes;
enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;
enter.push(enterNodes);
update.push(updateNodes);
exit.push(exitNodes);
}
var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);
if (typeof value === "function") {
while (++i < n) {
bind(group = this[i], value.call(group, group.parentNode.__data__, i));
}
} else {
while (++i < n) {
bind(group = this[i], value);
}
}
update.enter = function() {
return enter;
};
update.exit = function() {
return exit;
};
return update;
};
function d3_selection_dataNode(data) {
return {
__data__: data
};
}
d3_selectionPrototype.datum = function(value) {
return arguments.length ? this.property("__data__", value) : this.property("__data__");
};
d3_selectionPrototype.filter = function(filter) {
var subgroups = [], subgroup, group, node;
if (typeof filter !== "function") filter = d3_selection_filter(filter);
for (var j = 0, m = this.length; j < m; j++) {
subgroups.push(subgroup = []);
subgroup.parentNode = (group = this[j]).parentNode;
for (var i = 0, n = group.length; i < n; i++) {
if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
subgroup.push(node);
}
}
}
return d3_selection(subgroups);
};
function d3_selection_filter(selector) {
return function() {
return d3_selectMatches(this, selector);
};
}
d3_selectionPrototype.order = function() {
for (var j = -1, m = this.length; ++j < m; ) {
for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {
if (node = group[i]) {
if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
next = node;
}
}
}
return this;
};
d3_selectionPrototype.sort = function(comparator) {
comparator = d3_selection_sortComparator.apply(this, arguments);
for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);
return this.order();
};
function d3_selection_sortComparator(comparator) {
if (!arguments.length) comparator = d3_ascending;
return function(a, b) {
return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
};
}
d3_selectionPrototype.each = function(callback) {
return d3_selection_each(this, function(node, i, j) {
callback.call(node, node.__data__, i, j);
});
};
function d3_selection_each(groups, callback) {
for (var j = 0, m = groups.length; j < m; j++) {
for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
if (node = group[i]) callback(node, i, j);
}
}
return groups;
}
d3_selectionPrototype.call = function(callback) {
var args = d3_array(arguments);
callback.apply(args[0] = this, args);
return this;
};
d3_selectionPrototype.empty = function() {
return !this.node();
};
d3_selectionPrototype.node = function() {
for (var j = 0, m = this.length; j < m; j++) {
for (var group = this[j], i = 0, n = group.length; i < n; i++) {
var node = group[i];
if (node) return node;
}
}
return null;
};
d3_selectionPrototype.size = function() {
var n = 0;
this.each(function() {
++n;
});
return n;
};
function d3_selection_enter(selection) {
d3_subclass(selection, d3_selection_enterPrototype);
return selection;
}
var d3_selection_enterPrototype = [];
d3.selection.enter = d3_selection_enter;
d3.selection.enter.prototype = d3_selection_enterPrototype;
d3_selection_enterPrototype.append = d3_selectionPrototype.append;
d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
d3_selection_enterPrototype.node = d3_selectionPrototype.node;
d3_selection_enterPrototype.call = d3_selectionPrototype.call;
d3_selection_enterPrototype.size = d3_selectionPrototype.size;
d3_selection_enterPrototype.select = function(selector) {
var subgroups = [], subgroup, subnode, upgroup, group, node;
for (var j = -1, m = this.length; ++j < m; ) {
upgroup = (group = this[j]).update;
subgroups.push(subgroup = []);
subgroup.parentNode = group.parentNode;
for (var i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) {
subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));
subnode.__data__ = node.__data__;
} else {
subgroup.push(null);
}
}
}
return d3_selection(subgroups);
};
d3_selection_enterPrototype.insert = function(name, before) {
if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);
return d3_selectionPrototype.insert.call(this, name, before);
};
function d3_selection_enterInsertBefore(enter) {
var i0, j0;
return function(d, i, j) {
var group = enter[j].update, n = group.length, node;
if (j != j0) j0 = j, i0 = 0;
if (i >= i0) i0 = i + 1;
while (!(node = group[i0]) && ++i0 < n) ;
return node;
};
}
d3_selectionPrototype.transition = function() {
var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || {
time: Date.now(),
ease: d3_ease_cubicInOut,
delay: 0,
duration: 250
};
for (var j = -1, m = this.length; ++j < m; ) {
subgroups.push(subgroup = []);
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) d3_transitionNode(node, i, id, transition);
subgroup.push(node);
}
}
return d3_transition(subgroups, id);
};
d3_selectionPrototype.interrupt = function() {
return this.each(d3_selection_interrupt);
};
function d3_selection_interrupt() {
var lock = this.__transition__;
if (lock) ++lock.active;
}
d3.select = function(node) {
var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ];
group.parentNode = d3_documentElement;
return d3_selection([ group ]);
};
d3.selectAll = function(nodes) {
var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes);
group.parentNode = d3_documentElement;
return d3_selection([ group ]);
};
var d3_selectionRoot = d3.select(d3_documentElement);
d3_selectionPrototype.on = function(type, listener, capture) {
var n = arguments.length;
if (n < 3) {
if (typeof type !== "string") {
if (n < 2) listener = false;
for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));
return this;
}
if (n < 2) return (n = this.node()["__on" + type]) && n._;
capture = false;
}
return this.each(d3_selection_on(type, listener, capture));
};
function d3_selection_on(type, listener, capture) {
var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener;
if (i > 0) type = type.substring(0, i);
var filter = d3_selection_onFilters.get(type);
if (filter) type = filter, wrap = d3_selection_onFilter;
function onRemove() {
var l = this[name];
if (l) {
this.removeEventListener(type, l, l.$);
delete this[name];
}
}
function onAdd() {
var l = wrap(listener, d3_array(arguments));
onRemove.call(this);
this.addEventListener(type, this[name] = l, l.$ = capture);
l._ = listener;
}
function removeAll() {
var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match;
for (var name in this) {
if (match = name.match(re)) {
var l = this[name];
this.removeEventListener(match[1], l, l.$);
delete this[name];
}
}
}
return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;
}
var d3_selection_onFilters = d3.map({
mouseenter: "mouseover",
mouseleave: "mouseout"
});
d3_selection_onFilters.forEach(function(k) {
if ("on" + k in d3_document) d3_selection_onFilters.remove(k);
});
function d3_selection_onListener(listener, argumentz) {
return function(e) {
var o = d3.event;
d3.event = e;
argumentz[0] = this.__data__;
try {
listener.apply(this, argumentz);
} finally {
d3.event = o;
}
};
}
function d3_selection_onFilter(listener, argumentz) {
var l = d3_selection_onListener(listener, argumentz);
return function(e) {
var target = this, related = e.relatedTarget;
if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {
l.call(target, e);
}
};
}
var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0;
function d3_event_dragSuppress() {
var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault);
if (d3_event_dragSelect) {
var style = d3_documentElement.style, select = style[d3_event_dragSelect];
style[d3_event_dragSelect] = "none";
}
return function(suppressClick) {
w.on(name, null);
if (d3_event_dragSelect) style[d3_event_dragSelect] = select;
if (suppressClick) {
function off() {
w.on(click, null);
}
w.on(click, function() {
d3_eventPreventDefault();
off();
}, true);
setTimeout(off, 0);
}
};
}
d3.mouse = function(container) {
return d3_mousePoint(container, d3_eventSource());
};
var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0;
function d3_mousePoint(container, e) {
if (e.changedTouches) e = e.changedTouches[0];
var svg = container.ownerSVGElement || container;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) {
svg = d3.select("body").append("svg").style({
position: "absolute",
top: 0,
left: 0,
margin: 0,
padding: 0,
border: "none"
}, "important");
var ctm = svg[0][0].getScreenCTM();
d3_mouse_bug44083 = !(ctm.f || ctm.e);
svg.remove();
}
if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX,
point.y = e.clientY;
point = point.matrixTransform(container.getScreenCTM().inverse());
return [ point.x, point.y ];
}
var rect = container.getBoundingClientRect();
return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];
}
d3.touches = function(container, touches) {
if (arguments.length < 2) touches = d3_eventSource().touches;
return touches ? d3_array(touches).map(function(touch) {
var point = d3_mousePoint(container, touch);
point.identifier = touch.identifier;
return point;
}) : [];
};
d3.behavior.drag = function() {
var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_behavior_dragMouseSubject, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_behavior_dragTouchSubject, "touchmove", "touchend");
function drag() {
this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart);
}
function dragstart(id, position, subject, move, end) {
return function() {
var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(), position0 = position(parent, dragId);
if (origin) {
dragOffset = origin.apply(that, arguments);
dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];
} else {
dragOffset = [ 0, 0 ];
}
dispatch({
type: "dragstart"
});
function moved() {
var position1 = position(parent, dragId), dx, dy;
if (!position1) return;
dx = position1[0] - position0[0];
dy = position1[1] - position0[1];
dragged |= dx | dy;
position0 = position1;
dispatch({
type: "drag",
x: position1[0] + dragOffset[0],
y: position1[1] + dragOffset[1],
dx: dx,
dy: dy
});
}
function ended() {
if (!position(parent, dragId)) return;
dragSubject.on(move + dragName, null).on(end + dragName, null);
dragRestore(dragged && d3.event.target === target);
dispatch({
type: "dragend"
});
}
};
}
drag.origin = function(x) {
if (!arguments.length) return origin;
origin = x;
return drag;
};
return d3.rebind(drag, event, "on");
};
function d3_behavior_dragTouchId() {
return d3.event.changedTouches[0].identifier;
}
function d3_behavior_dragTouchSubject() {
return d3.event.target;
}
function d3_behavior_dragMouseSubject() {
return d3_window;
}
var π = Math.PI, τ = 2 * π, halfπ = π / 2, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π;
function d3_sgn(x) {
return x > 0 ? 1 : x < 0 ? -1 : 0;
}
function d3_cross2d(a, b, c) {
return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
}
function d3_acos(x) {
return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
}
function d3_asin(x) {
return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
}
function d3_sinh(x) {
return ((x = Math.exp(x)) - 1 / x) / 2;
}
function d3_cosh(x) {
return ((x = Math.exp(x)) + 1 / x) / 2;
}
function d3_tanh(x) {
return ((x = Math.exp(2 * x)) - 1) / (x + 1);
}
function d3_haversin(x) {
return (x = Math.sin(x / 2)) * x;
}
var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;
d3.interpolateZoom = function(p0, p1) {
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2];
var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ;
function interpolate(t) {
var s = t * S;
if (dr) {
var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];
}
return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ];
}
interpolate.duration = S * 1e3;
return interpolate;
};
d3.behavior.zoom = function() {
var view = {
x: 0,
y: 0,
k: 1
}, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
function zoom(g) {
g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
}
zoom.event = function(g) {
g.each(function() {
var dispatch = event.of(this, arguments), view1 = view;
if (d3_transitionInheritId) {
d3.select(this).transition().each("start.zoom", function() {
view = this.__chart__ || {
x: 0,
y: 0,
k: 1
};
zoomstarted(dispatch);
}).tween("zoom:zoom", function() {
var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);
return function(t) {
var l = i(t), k = dx / l[2];
this.__chart__ = view = {
x: cx - l[0] * k,
y: cy - l[1] * k,
k: k
};
zoomed(dispatch);
};
}).each("end.zoom", function() {
zoomended(dispatch);
});
} else {
this.__chart__ = view;
zoomstarted(dispatch);
zoomed(dispatch);
zoomended(dispatch);
}
});
};
zoom.translate = function(_) {
if (!arguments.length) return [ view.x, view.y ];
view = {
x: +_[0],
y: +_[1],
k: view.k
};
rescale();
return zoom;
};
zoom.scale = function(_) {
if (!arguments.length) return view.k;
view = {
x: view.x,
y: view.y,
k: +_
};
rescale();
return zoom;
};
zoom.scaleExtent = function(_) {
if (!arguments.length) return scaleExtent;
scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];
return zoom;
};
zoom.center = function(_) {
if (!arguments.length) return center;
center = _ && [ +_[0], +_[1] ];
return zoom;
};
zoom.size = function(_) {
if (!arguments.length) return size;
size = _ && [ +_[0], +_[1] ];
return zoom;
};
zoom.x = function(z) {
if (!arguments.length) return x1;
x1 = z;
x0 = z.copy();
view = {
x: 0,
y: 0,
k: 1
};
return zoom;
};
zoom.y = function(z) {
if (!arguments.length) return y1;
y1 = z;
y0 = z.copy();
view = {
x: 0,
y: 0,
k: 1
};
return zoom;
};
function location(p) {
return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];
}
function point(l) {
return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];
}
function scaleTo(s) {
view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
}
function translateTo(p, l) {
l = point(l);
view.x += p[0] - l[0];
view.y += p[1] - l[1];
}
function rescale() {
if (x1) x1.domain(x0.range().map(function(x) {
return (x - view.x) / view.k;
}).map(x0.invert));
if (y1) y1.domain(y0.range().map(function(y) {
return (y - view.y) / view.k;
}).map(y0.invert));
}
function zoomstarted(dispatch) {
dispatch({
type: "zoomstart"
});
}
function zoomed(dispatch) {
rescale();
dispatch({
type: "zoom",
scale: view.k,
translate: [ view.x, view.y ]
});
}
function zoomended(dispatch) {
dispatch({
type: "zoomend"
});
}
function mousedowned() {
var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress();
d3_selection_interrupt.call(that);
zoomstarted(dispatch);
function moved() {
dragged = 1;
translateTo(d3.mouse(that), location0);
zoomed(dispatch);
}
function ended() {
subject.on(mousemove, null).on(mouseup, null);
dragRestore(dragged && d3.event.target === target);
zoomended(dispatch);
}
}
function touchstarted() {
var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
d3_selection_interrupt.call(that);
started();
zoomstarted(dispatch);
function relocate() {
var touches = d3.touches(that);
scale0 = view.k;
touches.forEach(function(t) {
if (t.identifier in locations0) locations0[t.identifier] = location(t);
});
return touches;
}
function started() {
var target = d3.event.target;
d3.select(target).on(touchmove, moved).on(touchend, ended);
targets.push(target);
var changed = d3.event.changedTouches;
for (var i = 0, n = changed.length; i < n; ++i) {
locations0[changed[i].identifier] = null;
}
var touches = relocate(), now = Date.now();
if (touches.length === 1) {
if (now - touchtime < 500) {
var p = touches[0], l = locations0[p.identifier];
scaleTo(view.k * 2);
translateTo(p, l);
d3_eventPreventDefault();
zoomed(dispatch);
}
touchtime = now;
} else if (touches.length > 1) {
var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
distance0 = dx * dx + dy * dy;
}
}
function moved() {
var touches = d3.touches(that), p0, l0, p1, l1;
for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
p1 = touches[i];
if (l1 = locations0[p1.identifier]) {
if (l0) break;
p0 = p1, l0 = l1;
}
}
if (l1) {
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);
p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];
l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];
scaleTo(scale1 * scale0);
}
touchtime = null;
translateTo(p0, l0);
zoomed(dispatch);
}
function ended() {
if (d3.event.touches.length) {
var changed = d3.event.changedTouches;
for (var i = 0, n = changed.length; i < n; ++i) {
delete locations0[changed[i].identifier];
}
for (var identifier in locations0) {
return void relocate();
}
}
d3.selectAll(targets).on(zoomName, null);
subject.on(mousedown, mousedowned).on(touchstart, touchstarted);
dragRestore();
zoomended(dispatch);
}
}
function mousewheeled() {
var dispatch = event.of(this, arguments);
if (mousewheelTimer) clearTimeout(mousewheelTimer); else translate0 = location(center0 = center || d3.mouse(this)),
d3_selection_interrupt.call(this), zoomstarted(dispatch);
mousewheelTimer = setTimeout(function() {
mousewheelTimer = null;
zoomended(dispatch);
}, 50);
d3_eventPreventDefault();
scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
translateTo(center0, translate0);
zoomed(dispatch);
}
function dblclicked() {
var dispatch = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2;
zoomstarted(dispatch);
scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1));
translateTo(p, l);
zoomed(dispatch);
zoomended(dispatch);
}
return d3.rebind(zoom, event, "on");
};
var d3_behavior_zoomInfinity = [ 0, Infinity ];
var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() {
return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);
}, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() {
return d3.event.wheelDelta;
}, "mousewheel") : (d3_behavior_zoomDelta = function() {
return -d3.event.detail;
}, "MozMousePixelScroll");
d3.color = d3_color;
function d3_color() {}
d3_color.prototype.toString = function() {
return this.rgb() + "";
};
d3.hsl = d3_hsl;
function d3_hsl(h, s, l) {
return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l);
}
var d3_hslPrototype = d3_hsl.prototype = new d3_color();
d3_hslPrototype.brighter = function(k) {
k = Math.pow(.7, arguments.length ? k : 1);
return new d3_hsl(this.h, this.s, this.l / k);
};
d3_hslPrototype.darker = function(k) {
k = Math.pow(.7, arguments.length ? k : 1);
return new d3_hsl(this.h, this.s, k * this.l);
};
d3_hslPrototype.rgb = function() {
return d3_hsl_rgb(this.h, this.s, this.l);
};
function d3_hsl_rgb(h, s, l) {
var m1, m2;
h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;
s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;
l = l < 0 ? 0 : l > 1 ? 1 : l;
m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
m1 = 2 * l - m2;
function v(h) {
if (h > 360) h -= 360; else if (h < 0) h += 360;
if (h < 60) return m1 + (m2 - m1) * h / 60;
if (h < 180) return m2;
if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
return m1;
}
function vv(h) {
return Math.round(v(h) * 255);
}
return new d3_rgb(vv(h + 120), vv(h), vv(h - 120));
}
d3.hcl = d3_hcl;
function d3_hcl(h, c, l) {
return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l);
}
var d3_hclPrototype = d3_hcl.prototype = new d3_color();
d3_hclPrototype.brighter = function(k) {
return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));
};
d3_hclPrototype.darker = function(k) {
return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));
};
d3_hclPrototype.rgb = function() {
return d3_hcl_lab(this.h, this.c, this.l).rgb();
};
function d3_hcl_lab(h, c, l) {
if (isNaN(h)) h = 0;
if (isNaN(c)) c = 0;
return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);
}
d3.lab = d3_lab;
function d3_lab(l, a, b) {
return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b);
}
var d3_lab_K = 18;
var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;
var d3_labPrototype = d3_lab.prototype = new d3_color();
d3_labPrototype.brighter = function(k) {
return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
};
d3_labPrototype.darker = function(k) {
return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
};
d3_labPrototype.rgb = function() {
return d3_lab_rgb(this.l, this.a, this.b);
};
function d3_lab_rgb(l, a, b) {
var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
x = d3_lab_xyz(x) * d3_lab_X;
y = d3_lab_xyz(y) * d3_lab_Y;
z = d3_lab_xyz(z) * d3_lab_Z;
return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
}
function d3_lab_hcl(l, a, b) {
return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l);
}
function d3_lab_xyz(x) {
return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
}
function d3_xyz_lab(x) {
return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
}
function d3_xyz_rgb(r) {
return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));
}
d3.rgb = d3_rgb;
function d3_rgb(r, g, b) {
return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b);
}
function d3_rgbNumber(value) {
return new d3_rgb(value >> 16, value >> 8 & 255, value & 255);
}
function d3_rgbString(value) {
return d3_rgbNumber(value) + "";
}
var d3_rgbPrototype = d3_rgb.prototype = new d3_color();
d3_rgbPrototype.brighter = function(k) {
k = Math.pow(.7, arguments.length ? k : 1);
var r = this.r, g = this.g, b = this.b, i = 30;
if (!r && !g && !b) return new d3_rgb(i, i, i);
if (r && r < i) r = i;
if (g && g < i) g = i;
if (b && b < i) b = i;
return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k));
};
d3_rgbPrototype.darker = function(k) {
k = Math.pow(.7, arguments.length ? k : 1);
return new d3_rgb(k * this.r, k * this.g, k * this.b);
};
d3_rgbPrototype.hsl = function() {
return d3_rgb_hsl(this.r, this.g, this.b);
};
d3_rgbPrototype.toString = function() {
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
};
function d3_rgb_hex(v) {
return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
}
function d3_rgb_parse(format, rgb, hsl) {
var r = 0, g = 0, b = 0, m1, m2, color;
m1 = /([a-z]+)\((.*)\)/i.exec(format);
if (m1) {
m2 = m1[2].split(",");
switch (m1[1]) {
case "hsl":
{
return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);
}
case "rgb":
{
return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));
}
}
}
if (color = d3_rgb_names.get(format)) return rgb(color.r, color.g, color.b);
if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.substring(1), 16))) {
if (format.length === 4) {
r = (color & 3840) >> 4;
r = r >> 4 | r;
g = color & 240;
g = g >> 4 | g;
b = color & 15;
b = b << 4 | b;
} else if (format.length === 7) {
r = (color & 16711680) >> 16;
g = (color & 65280) >> 8;
b = color & 255;
}
}
return rgb(r, g, b);
}
function d3_rgb_hsl(r, g, b) {
var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;
if (d) {
s = l < .5 ? d / (max + min) : d / (2 - max - min);
if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;
h *= 60;
} else {
h = NaN;
s = l > 0 && l < 1 ? 0 : h;
}
return new d3_hsl(h, s, l);
}
function d3_rgb_lab(r, g, b) {
r = d3_rgb_xyz(r);
g = d3_rgb_xyz(g);
b = d3_rgb_xyz(b);
var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);
return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
}
function d3_rgb_xyz(r) {
return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);
}
function d3_rgb_parseNumber(c) {
var f = parseFloat(c);
return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
}
var d3_rgb_names = d3.map({
aliceblue: 15792383,
antiquewhite: 16444375,
aqua: 65535,
aquamarine: 8388564,
azure: 15794175,
beige: 16119260,
bisque: 16770244,
black: 0,
blanchedalmond: 16772045,
blue: 255,
blueviolet: 9055202,
brown: 10824234,
burlywood: 14596231,
cadetblue: 6266528,
chartreuse: 8388352,
chocolate: 13789470,
coral: 16744272,
cornflowerblue: 6591981,
cornsilk: 16775388,
crimson: 14423100,
cyan: 65535,
darkblue: 139,
darkcyan: 35723,
darkgoldenrod: 12092939,
darkgray: 11119017,
darkgreen: 25600,
darkgrey: 11119017,
darkkhaki: 12433259,
darkmagenta: 9109643,
darkolivegreen: 5597999,
darkorange: 16747520,
darkorchid: 10040012,
darkred: 9109504,
darksalmon: 15308410,
darkseagreen: 9419919,
darkslateblue: 4734347,
darkslategray: 3100495,
darkslategrey: 3100495,
darkturquoise: 52945,
darkviolet: 9699539,
deeppink: 16716947,
deepskyblue: 49151,
dimgray: 6908265,
dimgrey: 6908265,
dodgerblue: 2003199,
firebrick: 11674146,
floralwhite: 16775920,
forestgreen: 2263842,
fuchsia: 16711935,
gainsboro: 14474460,
ghostwhite: 16316671,
gold: 16766720,
goldenrod: 14329120,
gray: 8421504,
green: 32768,
greenyellow: 11403055,
grey: 8421504,
honeydew: 15794160,
hotpink: 16738740,
indianred: 13458524,
indigo: 4915330,
ivory: 16777200,
khaki: 15787660,
lavender: 15132410,
lavenderblush: 16773365,
lawngreen: 8190976,
lemonchiffon: 16775885,
lightblue: 11393254,
lightcoral: 15761536,
lightcyan: 14745599,
lightgoldenrodyellow: 16448210,
lightgray: 13882323,
lightgreen: 9498256,
lightgrey: 13882323,
lightpink: 16758465,
lightsalmon: 16752762,
lightseagreen: 2142890,
lightskyblue: 8900346,
lightslategray: 7833753,
lightslategrey: 7833753,
lightsteelblue: 11584734,
lightyellow: 16777184,
lime: 65280,
limegreen: 3329330,
linen: 16445670,
magenta: 16711935,
maroon: 8388608,
mediumaquamarine: 6737322,
mediumblue: 205,
mediumorchid: 12211667,
mediumpurple: 9662683,
mediumseagreen: 3978097,
mediumslateblue: 8087790,
mediumspringgreen: 64154,
mediumturquoise: 4772300,
mediumvioletred: 13047173,
midnightblue: 1644912,
mintcream: 16121850,
mistyrose: 16770273,
moccasin: 16770229,
navajowhite: 16768685,
navy: 128,
oldlace: 16643558,
olive: 8421376,
olivedrab: 7048739,
orange: 16753920,
orangered: 16729344,
orchid: 14315734,
palegoldenrod: 15657130,
palegreen: 10025880,
paleturquoise: 11529966,
palevioletred: 14381203,
papayawhip: 16773077,
peachpuff: 16767673,
peru: 13468991,
pink: 16761035,
plum: 14524637,
powderblue: 11591910,
purple: 8388736,
red: 16711680,
rosybrown: 12357519,
royalblue: 4286945,
saddlebrown: 9127187,
salmon: 16416882,
sandybrown: 16032864,
seagreen: 3050327,
seashell: 16774638,
sienna: 10506797,
silver: 12632256,
skyblue: 8900331,
slateblue: 6970061,
slategray: 7372944,
slategrey: 7372944,
snow: 16775930,
springgreen: 65407,
steelblue: 4620980,
tan: 13808780,
teal: 32896,
thistle: 14204888,
tomato: 16737095,
turquoise: 4251856,
violet: 15631086,
wheat: 16113331,
white: 16777215,
whitesmoke: 16119285,
yellow: 16776960,
yellowgreen: 10145074
});
d3_rgb_names.forEach(function(key, value) {
d3_rgb_names.set(key, d3_rgbNumber(value));
});
function d3_functor(v) {
return typeof v === "function" ? v : function() {
return v;
};
}
d3.functor = d3_functor;
function d3_identity(d) {
return d;
}
d3.xhr = d3_xhrType(d3_identity);
function d3_xhrType(response) {
return function(url, mimeType, callback) {
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType,
mimeType = null;
return d3_xhr(url, mimeType, response, callback);
};
}
function d3_xhr(url, mimeType, response, callback) {
var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null;
if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest();
"onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
request.readyState > 3 && respond();
};
function respond() {
var status = request.status, result;
if (!status && request.responseText || status >= 200 && status < 300 || status === 304) {
try {
result = response.call(xhr, request);
} catch (e) {
dispatch.error.call(xhr, e);
return;
}
dispatch.load.call(xhr, result);
} else {
dispatch.error.call(xhr, request);
}
}
request.onprogress = function(event) {
var o = d3.event;
d3.event = event;
try {
dispatch.progress.call(xhr, request);
} finally {
d3.event = o;
}
};
xhr.header = function(name, value) {
name = (name + "").toLowerCase();
if (arguments.length < 2) return headers[name];
if (value == null) delete headers[name]; else headers[name] = value + "";
return xhr;
};
xhr.mimeType = function(value) {
if (!arguments.length) return mimeType;
mimeType = value == null ? null : value + "";
return xhr;
};
xhr.responseType = function(value) {
if (!arguments.length) return responseType;
responseType = value;
return xhr;
};
xhr.response = function(value) {
response = value;
return xhr;
};
[ "get", "post" ].forEach(function(method) {
xhr[method] = function() {
return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments)));
};
});
xhr.send = function(method, data, callback) {
if (arguments.length === 2 && typeof data === "function") callback = data, data = null;
request.open(method, url, true);
if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*";
if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);
if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);
if (responseType != null) request.responseType = responseType;
if (callback != null) xhr.on("error", callback).on("load", function(request) {
callback(null, request);
});
dispatch.beforesend.call(xhr, request);
request.send(data == null ? null : data);
return xhr;
};
xhr.abort = function() {
request.abort();
return xhr;
};
d3.rebind(xhr, dispatch, "on");
return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));
}
function d3_xhr_fixCallback(callback) {
return callback.length === 1 ? function(error, request) {
callback(error == null ? request : null);
} : callback;
}
d3.dsv = function(delimiter, mimeType) {
var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0);
function dsv(url, row, callback) {
if (arguments.length < 3) callback = row, row = null;
var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback);
xhr.row = function(_) {
return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row;
};
return xhr;
}
function response(request) {
return dsv.parse(request.responseText);
}
function typedResponse(f) {
return function(request) {
return dsv.parse(request.responseText, f);
};
}
dsv.parse = function(text, f) {
var o;
return dsv.parseRows(text, function(row, i) {
if (o) return o(row, i - 1);
var a = new Function("d", "return {" + row.map(function(name, i) {
return JSON.stringify(name) + ": d[" + i + "]";
}).join(",") + "}");
o = f ? function(row, i) {
return f(a(row), i);
} : a;
});
};
dsv.parseRows = function(text, f) {
var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol;
function token() {
if (I >= N) return EOF;
if (eol) return eol = false, EOL;
var j = I;
if (text.charCodeAt(j) === 34) {
var i = j;
while (i++ < N) {
if (text.charCodeAt(i) === 34) {
if (text.charCodeAt(i + 1) !== 34) break;
++i;
}
}
I = i + 2;
var c = text.charCodeAt(i + 1);
if (c === 13) {
eol = true;
if (text.charCodeAt(i + 2) === 10) ++I;
} else if (c === 10) {
eol = true;
}
return text.substring(j + 1, i).replace(/""/g, '"');
}
while (I < N) {
var c = text.charCodeAt(I++), k = 1;
if (c === 10) eol = true; else if (c === 13) {
eol = true;
if (text.charCodeAt(I) === 10) ++I, ++k;
} else if (c !== delimiterCode) continue;
return text.substring(j, I - k);
}
return text.substring(j);
}
while ((t = token()) !== EOF) {
var a = [];
while (t !== EOL && t !== EOF) {
a.push(t);
t = token();
}
if (f && !(a = f(a, n++))) continue;
rows.push(a);
}
return rows;
};
dsv.format = function(rows) {
if (Array.isArray(rows[0])) return dsv.formatRows(rows);
var fieldSet = new d3_Set(), fields = [];
rows.forEach(function(row) {
for (var field in row) {
if (!fieldSet.has(field)) {
fields.push(fieldSet.add(field));
}
}
});
return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) {
return fields.map(function(field) {
return formatValue(row[field]);
}).join(delimiter);
})).join("\n");
};
dsv.formatRows = function(rows) {
return rows.map(formatRow).join("\n");
};
function formatRow(row) {
return row.map(formatValue).join(delimiter);
}
function formatValue(text) {
return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text;
}
return dsv;
};
d3.csv = d3.dsv(",", "text/csv");
d3.tsv = d3.dsv(" ", "text/tab-separated-values");
d3.touch = function(container, touches, identifier) {
if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches;
if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) {
if ((touch = touches[i]).identifier === identifier) {
return d3_mousePoint(container, touch);
}
}
};
var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) {
setTimeout(callback, 17);
};
d3.timer = function(callback, delay, then) {
var n = arguments.length;
if (n < 2) delay = 0;
if (n < 3) then = Date.now();
var time = then + delay, timer = {
c: callback,
t: time,
f: false,
n: null
};
if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer;
d3_timer_queueTail = timer;
if (!d3_timer_interval) {
d3_timer_timeout = clearTimeout(d3_timer_timeout);
d3_timer_interval = 1;
d3_timer_frame(d3_timer_step);
}
};
function d3_timer_step() {
var now = d3_timer_mark(), delay = d3_timer_sweep() - now;
if (delay > 24) {
if (isFinite(delay)) {
clearTimeout(d3_timer_timeout);
d3_timer_timeout = setTimeout(d3_timer_step, delay);
}
d3_timer_interval = 0;
} else {
d3_timer_interval = 1;
d3_timer_frame(d3_timer_step);
}
}
d3.timer.flush = function() {
d3_timer_mark();
d3_timer_sweep();
};
function d3_timer_mark() {
var now = Date.now();
d3_timer_active = d3_timer_queueHead;
while (d3_timer_active) {
if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t);
d3_timer_active = d3_timer_active.n;
}
return now;
}
function d3_timer_sweep() {
var t0, t1 = d3_timer_queueHead, time = Infinity;
while (t1) {
if (t1.f) {
t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;
} else {
if (t1.t < time) time = t1.t;
t1 = (t0 = t1).n;
}
}
d3_timer_queueTail = t0;
return time;
}
function d3_format_precision(x, p) {
return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1);
}
d3.round = function(x, n) {
return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);
};
var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix);
d3.formatPrefix = function(value, precision) {
var i = 0;
if (value) {
if (value < 0) value *= -1;
if (precision) value = d3.round(value, d3_format_precision(value, precision));
i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3));
}
return d3_formatPrefixes[8 + i / 3];
};
function d3_formatPrefix(d, i) {
var k = Math.pow(10, abs(8 - i) * 3);
return {
scale: i > 8 ? function(d) {
return d / k;
} : function(d) {
return d * k;
},
symbol: d
};
}
function d3_locale_numberFormat(locale) {
var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping ? function(value) {
var i = value.length, t = [], j = 0, g = locale_grouping[0];
while (i > 0 && g > 0) {
t.push(value.substring(i -= g, i + g));
g = locale_grouping[j = (j + 1) % locale_grouping.length];
}
return t.reverse().join(locale_thousands);
} : d3_identity;
return function(specifier) {
var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false;
if (precision) precision = +precision.substring(1);
if (zfill || fill === "0" && align === "=") {
zfill = fill = "0";
align = "=";
if (comma) width -= Math.floor((width - 1) / 4);
}
switch (type) {
case "n":
comma = true;
type = "g";
break;
case "%":
scale = 100;
suffix = "%";
type = "f";
break;
case "p":
scale = 100;
suffix = "%";
type = "r";
break;
case "b":
case "o":
case "x":
case "X":
if (symbol === "#") prefix = "0" + type.toLowerCase();
case "c":
case "d":
integer = true;
precision = 0;
break;
case "s":
scale = -1;
type = "r";
break;
}
if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1];
if (type == "r" && !precision) type = "g";
if (precision != null) {
if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision));
}
type = d3_format_types.get(type) || d3_format_typeDefault;
var zcomma = zfill && comma;
return function(value) {
var fullSuffix = suffix;
if (integer && value % 1) return "";
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign;
if (scale < 0) {
var unit = d3.formatPrefix(value, precision);
value = unit.scale(value);
fullSuffix = unit.symbol + suffix;
} else {
value *= scale;
}
value = type(value, precision);
var i = value.lastIndexOf("."), before = i < 0 ? value : value.substring(0, i), after = i < 0 ? "" : locale_decimal + value.substring(i + 1);
if (!zfill && comma) before = formatGroup(before);
var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : "";
if (zcomma) before = formatGroup(padding + before);
negative += prefix;
value = before + after;
return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix;
};
};
}
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;
var d3_format_types = d3.map({
b: function(x) {
return x.toString(2);
},
c: function(x) {
return String.fromCharCode(x);
},
o: function(x) {
return x.toString(8);
},
x: function(x) {
return x.toString(16);
},
X: function(x) {
return x.toString(16).toUpperCase();
},
g: function(x, p) {
return x.toPrecision(p);
},
e: function(x, p) {
return x.toExponential(p);
},
f: function(x, p) {
return x.toFixed(p);
},
r: function(x, p) {
return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p))));
}
});
function d3_format_typeDefault(x) {
return x + "";
}
var d3_time = d3.time = {}, d3_date = Date;
function d3_date_utc() {
this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]);
}
d3_date_utc.prototype = {
getDate: function() {
return this._.getUTCDate();
},
getDay: function() {
return this._.getUTCDay();
},
getFullYear: function() {
return this._.getUTCFullYear();
},
getHours: function() {
return this._.getUTCHours();
},
getMilliseconds: function() {
return this._.getUTCMilliseconds();
},
getMinutes: function() {
return this._.getUTCMinutes();
},
getMonth: function() {
return this._.getUTCMonth();
},
getSeconds: function() {
return this._.getUTCSeconds();
},
getTime: function() {
return this._.getTime();
},
getTimezoneOffset: function() {
return 0;
},
valueOf: function() {
return this._.valueOf();
},
setDate: function() {
d3_time_prototype.setUTCDate.apply(this._, arguments);
},
setDay: function() {
d3_time_prototype.setUTCDay.apply(this._, arguments);
},
setFullYear: function() {
d3_time_prototype.setUTCFullYear.apply(this._, arguments);
},
setHours: function() {
d3_time_prototype.setUTCHours.apply(this._, arguments);
},
setMilliseconds: function() {
d3_time_prototype.setUTCMilliseconds.apply(this._, arguments);
},
setMinutes: function() {
d3_time_prototype.setUTCMinutes.apply(this._, arguments);
},
setMonth: function() {
d3_time_prototype.setUTCMonth.apply(this._, arguments);
},
setSeconds: function() {
d3_time_prototype.setUTCSeconds.apply(this._, arguments);
},
setTime: function() {
d3_time_prototype.setTime.apply(this._, arguments);
}
};
var d3_time_prototype = Date.prototype;
function d3_time_interval(local, step, number) {
function round(date) {
var d0 = local(date), d1 = offset(d0, 1);
return date - d0 < d1 - date ? d0 : d1;
}
function ceil(date) {
step(date = local(new d3_date(date - 1)), 1);
return date;
}
function offset(date, k) {
step(date = new d3_date(+date), k);
return date;
}
function range(t0, t1, dt) {
var time = ceil(t0), times = [];
if (dt > 1) {
while (time < t1) {
if (!(number(time) % dt)) times.push(new Date(+time));
step(time, 1);
}
} else {
while (time < t1) times.push(new Date(+time)), step(time, 1);
}
return times;
}
function range_utc(t0, t1, dt) {
try {
d3_date = d3_date_utc;
var utc = new d3_date_utc();
utc._ = t0;
return range(utc, t1, dt);
} finally {
d3_date = Date;
}
}
local.floor = local;
local.round = round;
local.ceil = ceil;
local.offset = offset;
local.range = range;
var utc = local.utc = d3_time_interval_utc(local);
utc.floor = utc;
utc.round = d3_time_interval_utc(round);
utc.ceil = d3_time_interval_utc(ceil);
utc.offset = d3_time_interval_utc(offset);
utc.range = range_utc;
return local;
}
function d3_time_interval_utc(method) {
return function(date, k) {
try {
d3_date = d3_date_utc;
var utc = new d3_date_utc();
utc._ = date;
return method(utc, k)._;
} finally {
d3_date = Date;
}
};
}
d3_time.year = d3_time_interval(function(date) {
date = d3_time.day(date);
date.setMonth(0, 1);
return date;
}, function(date, offset) {
date.setFullYear(date.getFullYear() + offset);
}, function(date) {
return date.getFullYear();
});
d3_time.years = d3_time.year.range;
d3_time.years.utc = d3_time.year.utc.range;
d3_time.day = d3_time_interval(function(date) {
var day = new d3_date(2e3, 0);
day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
return day;
}, function(date, offset) {
date.setDate(date.getDate() + offset);
}, function(date) {
return date.getDate() - 1;
});
d3_time.days = d3_time.day.range;
d3_time.days.utc = d3_time.day.utc.range;
d3_time.dayOfYear = function(date) {
var year = d3_time.year(date);
return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5);
};
[ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) {
i = 7 - i;
var interval = d3_time[day] = d3_time_interval(function(date) {
(date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7);
return date;
}, function(date, offset) {
date.setDate(date.getDate() + Math.floor(offset) * 7);
}, function(date) {
var day = d3_time.year(date).getDay();
return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i);
});
d3_time[day + "s"] = interval.range;
d3_time[day + "s"].utc = interval.utc.range;
d3_time[day + "OfYear"] = function(date) {
var day = d3_time.year(date).getDay();
return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7);
};
});
d3_time.week = d3_time.sunday;
d3_time.weeks = d3_time.sunday.range;
d3_time.weeks.utc = d3_time.sunday.utc.range;
d3_time.weekOfYear = d3_time.sundayOfYear;
function d3_locale_timeFormat(locale) {
var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths;
function d3_time_format(template) {
var n = template.length;
function format(date) {
var string = [], i = -1, j = 0, c, p, f;
while (++i < n) {
if (template.charCodeAt(i) === 37) {
string.push(template.substring(j, i));
if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i);
if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p);
string.push(c);
j = i + 1;
}
}
string.push(template.substring(j, i));
return string.join("");
}
format.parse = function(string) {
var d = {
y: 1900,
m: 0,
d: 1,
H: 0,
M: 0,
S: 0,
L: 0,
Z: null
}, i = d3_time_parse(d, template, string, 0);
if (i != string.length) return null;
if ("p" in d) d.H = d.H % 12 + d.p * 12;
var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)();
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) {
date.setFullYear(d.y, 0, 1);
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
} else date.setFullYear(d.y, d.m, d.d);
date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L);
return localZ ? date._ : date;
};
format.toString = function() {
return template;
};
return format;
}
function d3_time_parse(date, template, string, j) {
var c, p, t, i = 0, n = template.length, m = string.length;
while (i < n) {
if (j >= m) return -1;
c = template.charCodeAt(i++);
if (c === 37) {
t = template.charAt(i++);
p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t];
if (!p || (j = p(date, string, j)) < 0) return -1;
} else if (c != string.charCodeAt(j++)) {
return -1;
}
}
return j;
}
d3_time_format.utc = function(template) {
var local = d3_time_format(template);
function format(date) {
try {
d3_date = d3_date_utc;
var utc = new d3_date();
utc._ = date;
return local(utc);
} finally {
d3_date = Date;
}
}
format.parse = function(string) {
try {
d3_date = d3_date_utc;
var date = local.parse(string);
return date && date._;
} finally {
d3_date = Date;
}
};
format.toString = local.toString;
return format;
};
d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti;
var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths);
locale_periods.forEach(function(p, i) {
d3_time_periodLookup.set(p.toLowerCase(), i);
});
var d3_time_formats = {
a: function(d) {
return locale_shortDays[d.getDay()];
},
A: function(d) {
return locale_days[d.getDay()];
},
b: function(d) {
return locale_shortMonths[d.getMonth()];
},
B: function(d) {
return locale_months[d.getMonth()];
},
c: d3_time_format(locale_dateTime),
d: function(d, p) {
return d3_time_formatPad(d.getDate(), p, 2);
},
e: function(d, p) {
return d3_time_formatPad(d.getDate(), p, 2);
},
H: function(d, p) {
return d3_time_formatPad(d.getHours(), p, 2);
},
I: function(d, p) {
return d3_time_formatPad(d.getHours() % 12 || 12, p, 2);
},
j: function(d, p) {
return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3);
},
L: function(d, p) {
return d3_time_formatPad(d.getMilliseconds(), p, 3);
},
m: function(d, p) {
return d3_time_formatPad(d.getMonth() + 1, p, 2);
},
M: function(d, p) {
return d3_time_formatPad(d.getMinutes(), p, 2);
},
p: function(d) {
return locale_periods[+(d.getHours() >= 12)];
},
S: function(d, p) {
return d3_time_formatPad(d.getSeconds(), p, 2);
},
U: function(d, p) {
return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2);
},
w: function(d) {
return d.getDay();
},
W: function(d, p) {
return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2);
},
x: d3_time_format(locale_date),
X: d3_time_format(locale_time),
y: function(d, p) {
return d3_time_formatPad(d.getFullYear() % 100, p, 2);
},
Y: function(d, p) {
return d3_time_formatPad(d.getFullYear() % 1e4, p, 4);
},
Z: d3_time_zone,
"%": function() {
return "%";
}
};
var d3_time_parsers = {
a: d3_time_parseWeekdayAbbrev,
A: d3_time_parseWeekday,
b: d3_time_parseMonthAbbrev,
B: d3_time_parseMonth,
c: d3_time_parseLocaleFull,
d: d3_time_parseDay,
e: d3_time_parseDay,
H: d3_time_parseHour24,
I: d3_time_parseHour24,
j: d3_time_parseDayOfYear,
L: d3_time_parseMilliseconds,
m: d3_time_parseMonthNumber,
M: d3_time_parseMinutes,
p: d3_time_parseAmPm,
S: d3_time_parseSeconds,
U: d3_time_parseWeekNumberSunday,
w: d3_time_parseWeekdayNumber,
W: d3_time_parseWeekNumberMonday,
x: d3_time_parseLocaleDate,
X: d3_time_parseLocaleTime,
y: d3_time_parseYear,
Y: d3_time_parseFullYear,
Z: d3_time_parseZone,
"%": d3_time_parseLiteralPercent
};
function d3_time_parseWeekdayAbbrev(date, string, i) {
d3_time_dayAbbrevRe.lastIndex = 0;
var n = d3_time_dayAbbrevRe.exec(string.substring(i));
return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function d3_time_parseWeekday(date, string, i) {
d3_time_dayRe.lastIndex = 0;
var n = d3_time_dayRe.exec(string.substring(i));
return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function d3_time_parseMonthAbbrev(date, string, i) {
d3_time_monthAbbrevRe.lastIndex = 0;
var n = d3_time_monthAbbrevRe.exec(string.substring(i));
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function d3_time_parseMonth(date, string, i) {
d3_time_monthRe.lastIndex = 0;
var n = d3_time_monthRe.exec(string.substring(i));
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
}
function d3_time_parseLocaleFull(date, string, i) {
return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
}
function d3_time_parseLocaleDate(date, string, i) {
return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
}
function d3_time_parseLocaleTime(date, string, i) {
return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
}
function d3_time_parseAmPm(date, string, i) {
var n = d3_time_periodLookup.get(string.substring(i, i += 2).toLowerCase());
return n == null ? -1 : (date.p = n, i);
}
return d3_time_format;
}
var d3_time_formatPads = {
"-": "",
_: " ",
"0": "0"
}, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/;
function d3_time_formatPad(value, fill, width) {
var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length;
return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
}
function d3_time_formatRe(names) {
return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i");
}
function d3_time_formatLookup(names) {
var map = new d3_Map(), i = -1, n = names.length;
while (++i < n) map.set(names[i].toLowerCase(), i);
return map;
}
function d3_time_parseWeekdayNumber(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 1));
return n ? (date.w = +n[0], i + n[0].length) : -1;
}
function d3_time_parseWeekNumberSunday(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i));
return n ? (date.U = +n[0], i + n[0].length) : -1;
}
function d3_time_parseWeekNumberMonday(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i));
return n ? (date.W = +n[0], i + n[0].length) : -1;
}
function d3_time_parseFullYear(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 4));
return n ? (date.y = +n[0], i + n[0].length) : -1;
}
function d3_time_parseYear(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
}
function d3_time_parseZone(date, string, i) {
return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = -string,
i + 5) : -1;
}
function d3_time_expandYear(d) {
return d + (d > 68 ? 1900 : 2e3);
}
function d3_time_parseMonthNumber(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.m = n[0] - 1, i + n[0].length) : -1;
}
function d3_time_parseDay(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.d = +n[0], i + n[0].length) : -1;
}
function d3_time_parseDayOfYear(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 3));
return n ? (date.j = +n[0], i + n[0].length) : -1;
}
function d3_time_parseHour24(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.H = +n[0], i + n[0].length) : -1;
}
function d3_time_parseMinutes(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.M = +n[0], i + n[0].length) : -1;
}
function d3_time_parseSeconds(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.S = +n[0], i + n[0].length) : -1;
}
function d3_time_parseMilliseconds(date, string, i) {
d3_time_numberRe.lastIndex = 0;
var n = d3_time_numberRe.exec(string.substring(i, i + 3));
return n ? (date.L = +n[0], i + n[0].length) : -1;
}
function d3_time_zone(d) {
var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(abs(z) / 60), zm = abs(z) % 60;
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
}
function d3_time_parseLiteralPercent(date, string, i) {
d3_time_percentRe.lastIndex = 0;
var n = d3_time_percentRe.exec(string.substring(i, i + 1));
return n ? i + n[0].length : -1;
}
function d3_time_formatMulti(formats) {
var n = formats.length, i = -1;
while (++i < n) formats[i][0] = this(formats[i][0]);
return function(date) {
var i = 0, f = formats[i];
while (!f[1](date)) f = formats[++i];
return f[0](date);
};
}
d3.locale = function(locale) {
return {
numberFormat: d3_locale_numberFormat(locale),
timeFormat: d3_locale_timeFormat(locale)
};
};
var d3_locale_enUS = d3.locale({
decimal: ".",
thousands: ",",
grouping: [ 3 ],
currency: [ "$", "" ],
dateTime: "%a %b %e %X %Y",
date: "%m/%d/%Y",
time: "%H:%M:%S",
periods: [ "AM", "PM" ],
days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]
});
d3.format = d3_locale_enUS.numberFormat;
d3.geo = {};
function d3_adder() {}
d3_adder.prototype = {
s: 0,
t: 0,
add: function(y) {
d3_adderSum(y, this.t, d3_adderTemp);
d3_adderSum(d3_adderTemp.s, this.s, this);
if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t;
},
reset: function() {
this.s = this.t = 0;
},
valueOf: function() {
return this.s;
}
};
var d3_adderTemp = new d3_adder();
function d3_adderSum(a, b, o) {
var x = o.s = a + b, bv = x - a, av = x - bv;
o.t = a - av + (b - bv);
}
d3.geo.stream = function(object, listener) {
if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) {
d3_geo_streamObjectType[object.type](object, listener);
} else {
d3_geo_streamGeometry(object, listener);
}
};
function d3_geo_streamGeometry(geometry, listener) {
if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) {
d3_geo_streamGeometryType[geometry.type](geometry, listener);
}
}
var d3_geo_streamObjectType = {
Feature: function(feature, listener) {
d3_geo_streamGeometry(feature.geometry, listener);
},
FeatureCollection: function(object, listener) {
var features = object.features, i = -1, n = features.length;
while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener);
}
};
var d3_geo_streamGeometryType = {
Sphere: function(object, listener) {
listener.sphere();
},
Point: function(object, listener) {
object = object.coordinates;
listener.point(object[0], object[1], object[2]);
},
MultiPoint: function(object, listener) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]);
},
LineString: function(object, listener) {
d3_geo_streamLine(object.coordinates, listener, 0);
},
MultiLineString: function(object, listener) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0);
},
Polygon: function(object, listener) {
d3_geo_streamPolygon(object.coordinates, listener);
},
MultiPolygon: function(object, listener) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) d3_geo_streamPolygon(coordinates[i], listener);
},
GeometryCollection: function(object, listener) {
var geometries = object.geometries, i = -1, n = geometries.length;
while (++i < n) d3_geo_streamGeometry(geometries[i], listener);
}
};
function d3_geo_streamLine(coordinates, listener, closed) {
var i = -1, n = coordinates.length - closed, coordinate;
listener.lineStart();
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]);
listener.lineEnd();
}
function d3_geo_streamPolygon(coordinates, listener) {
var i = -1, n = coordinates.length;
listener.polygonStart();
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);
listener.polygonEnd();
}
d3.geo.area = function(object) {
d3_geo_areaSum = 0;
d3.geo.stream(object, d3_geo_area);
return d3_geo_areaSum;
};
var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder();
var d3_geo_area = {
sphere: function() {
d3_geo_areaSum += 4 * π;
},
point: d3_noop,
lineStart: d3_noop,
lineEnd: d3_noop,
polygonStart: function() {
d3_geo_areaRingSum.reset();
d3_geo_area.lineStart = d3_geo_areaRingStart;
},
polygonEnd: function() {
var area = 2 * d3_geo_areaRingSum;
d3_geo_areaSum += area < 0 ? 4 * π + area : area;
d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;
}
};
function d3_geo_areaRingStart() {
var λ00, φ00, λ0, cosφ0, sinφ0;
d3_geo_area.point = function(λ, φ) {
d3_geo_area.point = nextPoint;
λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4),
sinφ0 = Math.sin(φ);
};
function nextPoint(λ, φ) {
λ *= d3_radians;
φ = φ * d3_radians / 2 + π / 4;
var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ);
d3_geo_areaRingSum.add(Math.atan2(v, u));
λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ;
}
d3_geo_area.lineEnd = function() {
nextPoint(λ00, φ00);
};
}
function d3_geo_cartesian(spherical) {
var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ);
return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ];
}
function d3_geo_cartesianDot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
function d3_geo_cartesianCross(a, b) {
return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ];
}
function d3_geo_cartesianAdd(a, b) {
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}
function d3_geo_cartesianScale(vector, k) {
return [ vector[0] * k, vector[1] * k, vector[2] * k ];
}
function d3_geo_cartesianNormalize(d) {
var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
d[0] /= l;
d[1] /= l;
d[2] /= l;
}
function d3_geo_spherical(cartesian) {
return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ];
}
function d3_geo_sphericalEqual(a, b) {
return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε;
}
d3.geo.bounds = function() {
var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range;
var bound = {
point: point,
lineStart: lineStart,
lineEnd: lineEnd,
polygonStart: function() {
bound.point = ringPoint;
bound.lineStart = ringStart;
bound.lineEnd = ringEnd;
dλSum = 0;
d3_geo_area.polygonStart();
},
polygonEnd: function() {
d3_geo_area.polygonEnd();
bound.point = point;
bound.lineStart = lineStart;
bound.lineEnd = lineEnd;
if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90;
range[0] = λ0, range[1] = λ1;
}
};
function point(λ, φ) {
ranges.push(range = [ λ0 = λ, λ1 = λ ]);
if (φ < φ0) φ0 = φ;
if (φ > φ1) φ1 = φ;
}
function linePoint(λ, φ) {
var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]);
if (p0) {
var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal);
d3_geo_cartesianNormalize(inflection);
inflection = d3_geo_spherical(inflection);
var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180;
if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
var φi = inflection[1] * d3_degrees;
if (φi > φ1) φ1 = φi;
} else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
var φi = -inflection[1] * d3_degrees;
if (φi < φ0) φ0 = φi;
} else {
if (φ < φ0) φ0 = φ;
if (φ > φ1) φ1 = φ;
}
if (antimeridian) {
if (λ < λ_) {
if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
} else {
if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
}
} else {
if (λ1 >= λ0) {
if (λ < λ0) λ0 = λ;
if (λ > λ1) λ1 = λ;
} else {
if (λ > λ_) {
if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
} else {
if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
}
}
}
} else {
point(λ, φ);
}
p0 = p, λ_ = λ;
}
function lineStart() {
bound.point = linePoint;
}
function lineEnd() {
range[0] = λ0, range[1] = λ1;
bound.point = point;
p0 = null;
}
function ringPoint(λ, φ) {
if (p0) {
var dλ = λ - λ_;
dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;
} else λ__ = λ, φ__ = φ;
d3_geo_area.point(λ, φ);
linePoint(λ, φ);
}
function ringStart() {
d3_geo_area.lineStart();
}
function ringEnd() {
ringPoint(λ__, φ__);
d3_geo_area.lineEnd();
if (abs(dλSum) > ε) λ0 = -(λ1 = 180);
range[0] = λ0, range[1] = λ1;
p0 = null;
}
function angle(λ0, λ1) {
return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1;
}
function compareRanges(a, b) {
return a[0] - b[0];
}
function withinRange(x, range) {
return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
}
return function(feature) {
φ1 = λ1 = -(λ0 = φ0 = Infinity);
ranges = [];
d3.geo.stream(feature, bound);
var n = ranges.length;
if (n) {
ranges.sort(compareRanges);
for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) {
b = ranges[i];
if (withinRange(b[0], a) || withinRange(b[1], a)) {
if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
} else {
merged.push(a = b);
}
}
var best = -Infinity, dλ;
for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) {
b = merged[i];
if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1];
}
}
ranges = range = null;
return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ];
};
}();
d3.geo.centroid = function(object) {
d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;
d3.geo.stream(object, d3_geo_centroid);
var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z;
if (m < ε2) {
x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1;
if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0;
m = x * x + y * y + z * z;
if (m < ε2) return [ NaN, NaN ];
}
return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ];
};
var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2;
var d3_geo_centroid = {
sphere: d3_noop,
point: d3_geo_centroidPoint,
lineStart: d3_geo_centroidLineStart,
lineEnd: d3_geo_centroidLineEnd,
polygonStart: function() {
d3_geo_centroid.lineStart = d3_geo_centroidRingStart;
},
polygonEnd: function() {
d3_geo_centroid.lineStart = d3_geo_centroidLineStart;
}
};
function d3_geo_centroidPoint(λ, φ) {
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians);
d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ));
}
function d3_geo_centroidPointXYZ(x, y, z) {
++d3_geo_centroidW0;
d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0;
d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0;
d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0;
}
function d3_geo_centroidLineStart() {
var x0, y0, z0;
d3_geo_centroid.point = function(λ, φ) {
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians);
x0 = cosφ * Math.cos(λ);
y0 = cosφ * Math.sin(λ);
z0 = Math.sin(φ);
d3_geo_centroid.point = nextPoint;
d3_geo_centroidPointXYZ(x0, y0, z0);
};
function nextPoint(λ, φ) {
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
d3_geo_centroidW1 += w;
d3_geo_centroidX1 += w * (x0 + (x0 = x));
d3_geo_centroidY1 += w * (y0 + (y0 = y));
d3_geo_centroidZ1 += w * (z0 + (z0 = z));
d3_geo_centroidPointXYZ(x0, y0, z0);
}
}
function d3_geo_centroidLineEnd() {
d3_geo_centroid.point = d3_geo_centroidPoint;
}
function d3_geo_centroidRingStart() {
var λ00, φ00, x0, y0, z0;
d3_geo_centroid.point = function(λ, φ) {
λ00 = λ, φ00 = φ;
d3_geo_centroid.point = nextPoint;
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians);
x0 = cosφ * Math.cos(λ);
y0 = cosφ * Math.sin(λ);
z0 = Math.sin(φ);
d3_geo_centroidPointXYZ(x0, y0, z0);
};
d3_geo_centroid.lineEnd = function() {
nextPoint(λ00, φ00);
d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd;
d3_geo_centroid.point = d3_geo_centroidPoint;
};
function nextPoint(λ, φ) {
λ *= d3_radians;
var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u);
d3_geo_centroidX2 += v * cx;
d3_geo_centroidY2 += v * cy;
d3_geo_centroidZ2 += v * cz;
d3_geo_centroidW1 += w;
d3_geo_centroidX1 += w * (x0 + (x0 = x));
d3_geo_centroidY1 += w * (y0 + (y0 = y));
d3_geo_centroidZ1 += w * (z0 + (z0 = z));
d3_geo_centroidPointXYZ(x0, y0, z0);
}
}
function d3_true() {
return true;
}
function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) {
var subject = [], clip = [];
segments.forEach(function(segment) {
if ((n = segment.length - 1) <= 0) return;
var n, p0 = segment[0], p1 = segment[n];
if (d3_geo_sphericalEqual(p0, p1)) {
listener.lineStart();
for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]);
listener.lineEnd();
return;
}
var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false);
a.o = b;
subject.push(a);
clip.push(b);
a = new d3_geo_clipPolygonIntersection(p1, segment, null, false);
b = new d3_geo_clipPolygonIntersection(p1, null, a, true);
a.o = b;
subject.push(a);
clip.push(b);
});
clip.sort(compare);
d3_geo_clipPolygonLinkCircular(subject);
d3_geo_clipPolygonLinkCircular(clip);
if (!subject.length) return;
for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) {
clip[i].e = entry = !entry;
}
var start = subject[0], points, point;
while (1) {
var current = start, isSubject = true;
while (current.v) if ((current = current.n) === start) return;
points = current.z;
listener.lineStart();
do {
current.v = current.o.v = true;
if (current.e) {
if (isSubject) {
for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]);
} else {
interpolate(current.x, current.n.x, 1, listener);
}
current = current.n;
} else {
if (isSubject) {
points = current.p.z;
for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]);
} else {
interpolate(current.x, current.p.x, -1, listener);
}
current = current.p;
}
current = current.o;
points = current.z;
isSubject = !isSubject;
} while (!current.v);
listener.lineEnd();
}
}
function d3_geo_clipPolygonLinkCircular(array) {
if (!(n = array.length)) return;
var n, i = 0, a = array[0], b;
while (++i < n) {
a.n = b = array[i];
b.p = a;
a = b;
}
a.n = b = array[0];
b.p = a;
}
function d3_geo_clipPolygonIntersection(point, points, other, entry) {
this.x = point;
this.z = points;
this.o = other;
this.e = entry;
this.v = false;
this.n = this.p = null;
}
function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
return function(rotate, listener) {
var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]);
var clip = {
point: point,
lineStart: lineStart,
lineEnd: lineEnd,
polygonStart: function() {
clip.point = pointRing;
clip.lineStart = ringStart;
clip.lineEnd = ringEnd;
segments = [];
polygon = [];
},
polygonEnd: function() {
clip.point = point;
clip.lineStart = lineStart;
clip.lineEnd = lineEnd;
segments = d3.merge(segments);
var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);
if (segments.length) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);
} else if (clipStartInside) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
listener.lineStart();
interpolate(null, null, 1, listener);
listener.lineEnd();
}
if (polygonStarted) listener.polygonEnd(), polygonStarted = false;
segments = polygon = null;
},
sphere: function() {
listener.polygonStart();
listener.lineStart();
interpolate(null, null, 1, listener);
listener.lineEnd();
listener.polygonEnd();
}
};
function point(λ, φ) {
var point = rotate(λ, φ);
if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ);
}
function pointLine(λ, φ) {
var point = rotate(λ, φ);
line.point(point[0], point[1]);
}
function lineStart() {
clip.point = pointLine;
line.lineStart();
}
function lineEnd() {
clip.point = point;
line.lineEnd();
}
var segments;
var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring;
function pointRing(λ, φ) {
ring.push([ λ, φ ]);
var point = rotate(λ, φ);
ringListener.point(point[0], point[1]);
}
function ringStart() {
ringListener.lineStart();
ring = [];
}
function ringEnd() {
pointRing(ring[0][0], ring[0][1]);
ringListener.lineEnd();
var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length;
ring.pop();
polygon.push(ring);
ring = null;
if (!n) return;
if (clean & 1) {
segment = ringSegments[0];
var n = segment.length - 1, i = -1, point;
if (n > 0) {
if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
listener.lineStart();
while (++i < n) listener.point((point = segment[i])[0], point[1]);
listener.lineEnd();
}
return;
}
if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
segments.push(ringSegments.filter(d3_geo_clipSegmentLength1));
}
return clip;
};
}
function d3_geo_clipSegmentLength1(segment) {
return segment.length > 1;
}
function d3_geo_clipBufferListener() {
var lines = [], line;
return {
lineStart: function() {
lines.push(line = []);
},
point: function(λ, φ) {
line.push([ λ, φ ]);
},
lineEnd: d3_noop,
buffer: function() {
var buffer = lines;
lines = [];
line = null;
return buffer;
},
rejoin: function() {
if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
}
};
}
function d3_geo_clipSort(a, b) {
return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]);
}
function d3_geo_pointInPolygon(point, polygon) {
var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0;
d3_geo_areaRingSum.reset();
for (var i = 0, n = polygon.length; i < n; ++i) {
var ring = polygon[i], m = ring.length;
if (!m) continue;
var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1;
while (true) {
if (j === m) j = 0;
point = ring[j];
var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ;
d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ)));
polarAngle += antimeridian ? dλ + sdλ * τ : dλ;
if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) {
var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point));
d3_geo_cartesianNormalize(arc);
var intersection = d3_geo_cartesianCross(meridianNormal, arc);
d3_geo_cartesianNormalize(intersection);
var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]);
if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) {
winding += antimeridian ^ dλ >= 0 ? 1 : -1;
}
}
if (!j++) break;
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point;
}
}
return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1;
}
var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]);
function d3_geo_clipAntimeridianLine(listener) {
var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean;
return {
lineStart: function() {
listener.lineStart();
clean = 1;
},
point: function(λ1, φ1) {
var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0);
if (abs(dλ - π) < ε) {
listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ);
listener.point(sλ0, φ0);
listener.lineEnd();
listener.lineStart();
listener.point(sλ1, φ0);
listener.point(λ1, φ0);
clean = 0;
} else if (sλ0 !== sλ1 && dλ >= π) {
if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1);
listener.point(sλ0, φ0);
listener.lineEnd();
listener.lineStart();
listener.point(sλ1, φ0);
clean = 0;
}
listener.point(λ0 = λ1, φ0 = φ1);
sλ0 = sλ1;
},
lineEnd: function() {
listener.lineEnd();
λ0 = φ0 = NaN;
},
clean: function() {
return 2 - clean;
}
};
}
function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1);
return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;
}
function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
var φ;
if (from == null) {
φ = direction * halfπ;
listener.point(-π, φ);
listener.point(0, φ);
listener.point(π, φ);
listener.point(π, 0);
listener.point(π, -φ);
listener.point(0, -φ);
listener.point(-π, -φ);
listener.point(-π, 0);
listener.point(-π, φ);
} else if (abs(from[0] - to[0]) > ε) {
var s = from[0] < to[0] ? π : -π;
φ = direction * s / 2;
listener.point(-s, φ);
listener.point(0, φ);
listener.point(s, φ);
} else {
listener.point(to[0], to[1]);
}
}
function d3_geo_clipCircle(radius) {
var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians);
return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]);
function visible(λ, φ) {
return Math.cos(λ) * Math.cos(φ) > cr;
}
function clipLine(listener) {
var point0, c0, v0, v00, clean;
return {
lineStart: function() {
v00 = v0 = false;
clean = 1;
},
point: function(λ, φ) {
var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0;
if (!point0 && (v00 = v0 = v)) listener.lineStart();
if (v !== v0) {
point2 = intersect(point0, point1);
if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) {
point1[0] += ε;
point1[1] += ε;
v = visible(point1[0], point1[1]);
}
}
if (v !== v0) {
clean = 0;
if (v) {
listener.lineStart();
point2 = intersect(point1, point0);
listener.point(point2[0], point2[1]);
} else {
point2 = intersect(point0, point1);
listener.point(point2[0], point2[1]);
listener.lineEnd();
}
point0 = point2;
} else if (notHemisphere && point0 && smallRadius ^ v) {
var t;
if (!(c & c0) && (t = intersect(point1, point0, true))) {
clean = 0;
if (smallRadius) {
listener.lineStart();
listener.point(t[0][0], t[0][1]);
listener.point(t[1][0], t[1][1]);
listener.lineEnd();
} else {
listener.point(t[1][0], t[1][1]);
listener.lineEnd();
listener.lineStart();
listener.point(t[0][0], t[0][1]);
}
}
}
if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) {
listener.point(point1[0], point1[1]);
}
point0 = point1, v0 = v, c0 = c;
},
lineEnd: function() {
if (v0) listener.lineEnd();
point0 = null;
},
clean: function() {
return clean | (v00 && v0) << 1;
}
};
}
function intersect(a, b, two) {
var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b);
var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;
if (!determinant) return !two && a;
var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2);
d3_geo_cartesianAdd(A, B);
var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1);
if (t2 < 0) return;
var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu);
d3_geo_cartesianAdd(q, A);
q = d3_geo_spherical(q);
if (!two) return q;
var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z;
if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z;
var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε;
if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z;
if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) {
var q1 = d3_geo_cartesianScale(u, (-w + t) / uu);
d3_geo_cartesianAdd(q1, A);
return [ q, d3_geo_spherical(q1) ];
}
}
function code(λ, φ) {
var r = smallRadius ? radius : π - radius, code = 0;
if (λ < -r) code |= 1; else if (λ > r) code |= 2;
if (φ < -r) code |= 4; else if (φ > r) code |= 8;
return code;
}
}
function d3_geom_clipLine(x0, y0, x1, y1) {
return function(line) {
var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r;
r = x0 - ax;
if (!dx && r > 0) return;
r /= dx;
if (dx < 0) {
if (r < t0) return;
if (r < t1) t1 = r;
} else if (dx > 0) {
if (r > t1) return;
if (r > t0) t0 = r;
}
r = x1 - ax;
if (!dx && r < 0) return;
r /= dx;
if (dx < 0) {
if (r > t1) return;
if (r > t0) t0 = r;
} else if (dx > 0) {
if (r < t0) return;
if (r < t1) t1 = r;
}
r = y0 - ay;
if (!dy && r > 0) return;
r /= dy;
if (dy < 0) {
if (r < t0) return;
if (r < t1) t1 = r;
} else if (dy > 0) {
if (r > t1) return;
if (r > t0) t0 = r;
}
r = y1 - ay;
if (!dy && r < 0) return;
r /= dy;
if (dy < 0) {
if (r > t1) return;
if (r > t0) t0 = r;
} else if (dy > 0) {
if (r < t0) return;
if (r < t1) t1 = r;
}
if (t0 > 0) line.a = {
x: ax + t0 * dx,
y: ay + t0 * dy
};
if (t1 < 1) line.b = {
x: ax + t1 * dx,
y: ay + t1 * dy
};
return line;
};
}
var d3_geo_clipExtentMAX = 1e9;
d3.geo.clipExtent = function() {
var x0, y0, x1, y1, stream, clip, clipExtent = {
stream: function(output) {
if (stream) stream.valid = false;
stream = clip(output);
stream.valid = true;
return stream;
},
extent: function(_) {
if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];
clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]);
if (stream) stream.valid = false, stream = null;
return clipExtent;
}
};
return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]);
};
function d3_geo_clipExtent(x0, y0, x1, y1) {
return function(listener) {
var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring;
var clip = {
point: point,
lineStart: lineStart,
lineEnd: lineEnd,
polygonStart: function() {
listener = bufferListener;
segments = [];
polygon = [];
clean = true;
},
polygonEnd: function() {
listener = listener_;
segments = d3.merge(segments);
var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length;
if (inside || visible) {
listener.polygonStart();
if (inside) {
listener.lineStart();
interpolate(null, null, 1, listener);
listener.lineEnd();
}
if (visible) {
d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener);
}
listener.polygonEnd();
}
segments = polygon = ring = null;
}
};
function insidePolygon(p) {
var wn = 0, n = polygon.length, y = p[1];
for (var i = 0; i < n; ++i) {
for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) {
b = v[j];
if (a[1] <= y) {
if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn;
} else {
if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn;
}
a = b;
}
}
return wn !== 0;
}
function interpolate(from, to, direction, listener) {
var a = 0, a1 = 0;
if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) {
do {
listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
} while ((a = (a + direction + 4) % 4) !== a1);
} else {
listener.point(to[0], to[1]);
}
}
function pointVisible(x, y) {
return x0 <= x && x <= x1 && y0 <= y && y <= y1;
}
function point(x, y) {
if (pointVisible(x, y)) listener.point(x, y);
}
var x__, y__, v__, x_, y_, v_, first, clean;
function lineStart() {
clip.point = linePoint;
if (polygon) polygon.push(ring = []);
first = true;
v_ = false;
x_ = y_ = NaN;
}
function lineEnd() {
if (segments) {
linePoint(x__, y__);
if (v__ && v_) bufferListener.rejoin();
segments.push(bufferListener.buffer());
}
clip.point = point;
if (v_) listener.lineEnd();
}
function linePoint(x, y) {
x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));
y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));
var v = pointVisible(x, y);
if (polygon) ring.push([ x, y ]);
if (first) {
x__ = x, y__ = y, v__ = v;
first = false;
if (v) {
listener.lineStart();
listener.point(x, y);
}
} else {
if (v && v_) listener.point(x, y); else {
var l = {
a: {
x: x_,
y: y_
},
b: {
x: x,
y: y
}
};
if (clipLine(l)) {
if (!v_) {
listener.lineStart();
listener.point(l.a.x, l.a.y);
}
listener.point(l.b.x, l.b.y);
if (!v) listener.lineEnd();
clean = false;
} else if (v) {
listener.lineStart();
listener.point(x, y);
clean = false;
}
}
}
x_ = x, y_ = y, v_ = v;
}
return clip;
};
function corner(p, direction) {
return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2;
}
function compare(a, b) {
return comparePoints(a.x, b.x);
}
function comparePoints(a, b) {
var ca = corner(a, 1), cb = corner(b, 1);
return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0];
}
}
function d3_geo_compose(a, b) {
function compose(x, y) {
return x = a(x, y), b(x[0], x[1]);
}
if (a.invert && b.invert) compose.invert = function(x, y) {
return x = b.invert(x, y), x && a.invert(x[0], x[1]);
};
return compose;
}
function d3_geo_conic(projectAt) {
var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1);
p.parallels = function(_) {
if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ];
return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180);
};
return p;
}
function d3_geo_conicEqualArea(φ0, φ1) {
var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n;
function forward(λ, φ) {
var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n;
return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ];
}
forward.invert = function(x, y) {
var ρ0_y = ρ0 - y;
return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ];
};
return forward;
}
(d3.geo.conicEqualArea = function() {
return d3_geo_conic(d3_geo_conicEqualArea);
}).raw = d3_geo_conicEqualArea;
d3.geo.albers = function() {
return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070);
};
d3.geo.albersUsa = function() {
var lower48 = d3.geo.albers();
var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]);
var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]);
var point, pointStream = {
point: function(x, y) {
point = [ x, y ];
}
}, lower48Point, alaskaPoint, hawaiiPoint;
function albersUsa(coordinates) {
var x = coordinates[0], y = coordinates[1];
point = null;
(lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y);
return point;
}
albersUsa.invert = function(coordinates) {
var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k;
return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates);
};
albersUsa.stream = function(stream) {
var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream);
return {
point: function(x, y) {
lower48Stream.point(x, y);
alaskaStream.point(x, y);
hawaiiStream.point(x, y);
},
sphere: function() {
lower48Stream.sphere();
alaskaStream.sphere();
hawaiiStream.sphere();
},
lineStart: function() {
lower48Stream.lineStart();
alaskaStream.lineStart();
hawaiiStream.lineStart();
},
lineEnd: function() {
lower48Stream.lineEnd();
alaskaStream.lineEnd();
hawaiiStream.lineEnd();
},
polygonStart: function() {
lower48Stream.polygonStart();
alaskaStream.polygonStart();
hawaiiStream.polygonStart();
},
polygonEnd: function() {
lower48Stream.polygonEnd();
alaskaStream.polygonEnd();
hawaiiStream.polygonEnd();
}
};
};
albersUsa.precision = function(_) {
if (!arguments.length) return lower48.precision();
lower48.precision(_);
alaska.precision(_);
hawaii.precision(_);
return albersUsa;
};
albersUsa.scale = function(_) {
if (!arguments.length) return lower48.scale();
lower48.scale(_);
alaska.scale(_ * .35);
hawaii.scale(_);
return albersUsa.translate(lower48.translate());
};
albersUsa.translate = function(_) {
if (!arguments.length) return lower48.translate();
var k = lower48.scale(), x = +_[0], y = +_[1];
lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point;
alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;
hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;
return albersUsa;
};
return albersUsa.scale(1070);
};
var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = {
point: d3_noop,
lineStart: d3_noop,
lineEnd: d3_noop,
polygonStart: function() {
d3_geo_pathAreaPolygon = 0;
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
},
polygonEnd: function() {
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2);
}
};
function d3_geo_pathAreaRingStart() {
var x00, y00, x0, y0;
d3_geo_pathArea.point = function(x, y) {
d3_geo_pathArea.point = nextPoint;
x00 = x0 = x, y00 = y0 = y;
};
function nextPoint(x, y) {
d3_geo_pathAreaPolygon += y0 * x - x0 * y;
x0 = x, y0 = y;
}
d3_geo_pathArea.lineEnd = function() {
nextPoint(x00, y00);
};
}
var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1;
var d3_geo_pathBounds = {
point: d3_geo_pathBoundsPoint,
lineStart: d3_noop,
lineEnd: d3_noop,
polygonStart: d3_noop,
polygonEnd: d3_noop
};
function d3_geo_pathBoundsPoint(x, y) {
if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x;
if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x;
if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y;
if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y;
}
function d3_geo_pathBuffer() {
var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = [];
var stream = {
point: point,
lineStart: function() {
stream.point = pointLineStart;
},
lineEnd: lineEnd,
polygonStart: function() {
stream.lineEnd = lineEndPolygon;
},
polygonEnd: function() {
stream.lineEnd = lineEnd;
stream.point = point;
},
pointRadius: function(_) {
pointCircle = d3_geo_pathBufferCircle(_);
return stream;
},
result: function() {
if (buffer.length) {
var result = buffer.join("");
buffer = [];
return result;
}
}
};
function point(x, y) {
buffer.push("M", x, ",", y, pointCircle);
}
function pointLineStart(x, y) {
buffer.push("M", x, ",", y);
stream.point = pointLine;
}
function pointLine(x, y) {
buffer.push("L", x, ",", y);
}
function lineEnd() {
stream.point = point;
}
function lineEndPolygon() {
buffer.push("Z");
}
return stream;
}
function d3_geo_pathBufferCircle(radius) {
return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z";
}
var d3_geo_pathCentroid = {
point: d3_geo_pathCentroidPoint,
lineStart: d3_geo_pathCentroidLineStart,
lineEnd: d3_geo_pathCentroidLineEnd,
polygonStart: function() {
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;
},
polygonEnd: function() {
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;
d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;
}
};
function d3_geo_pathCentroidPoint(x, y) {
d3_geo_centroidX0 += x;
d3_geo_centroidY0 += y;
++d3_geo_centroidZ0;
}
function d3_geo_pathCentroidLineStart() {
var x0, y0;
d3_geo_pathCentroid.point = function(x, y) {
d3_geo_pathCentroid.point = nextPoint;
d3_geo_pathCentroidPoint(x0 = x, y0 = y);
};
function nextPoint(x, y) {
var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
d3_geo_centroidX1 += z * (x0 + x) / 2;
d3_geo_centroidY1 += z * (y0 + y) / 2;
d3_geo_centroidZ1 += z;
d3_geo_pathCentroidPoint(x0 = x, y0 = y);
}
}
function d3_geo_pathCentroidLineEnd() {
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
}
function d3_geo_pathCentroidRingStart() {
var x00, y00, x0, y0;
d3_geo_pathCentroid.point = function(x, y) {
d3_geo_pathCentroid.point = nextPoint;
d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y);
};
function nextPoint(x, y) {
var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
d3_geo_centroidX1 += z * (x0 + x) / 2;
d3_geo_centroidY1 += z * (y0 + y) / 2;
d3_geo_centroidZ1 += z;
z = y0 * x - x0 * y;
d3_geo_centroidX2 += z * (x0 + x);
d3_geo_centroidY2 += z * (y0 + y);
d3_geo_centroidZ2 += z * 3;
d3_geo_pathCentroidPoint(x0 = x, y0 = y);
}
d3_geo_pathCentroid.lineEnd = function() {
nextPoint(x00, y00);
};
}
function d3_geo_pathContext(context) {
var pointRadius = 4.5;
var stream = {
point: point,
lineStart: function() {
stream.point = pointLineStart;
},
lineEnd: lineEnd,
polygonStart: function() {
stream.lineEnd = lineEndPolygon;
},
polygonEnd: function() {
stream.lineEnd = lineEnd;
stream.point = point;
},
pointRadius: function(_) {
pointRadius = _;
return stream;
},
result: d3_noop
};
function point(x, y) {
context.moveTo(x, y);
context.arc(x, y, pointRadius, 0, τ);
}
function pointLineStart(x, y) {
context.moveTo(x, y);
stream.point = pointLine;
}
function pointLine(x, y) {
context.lineTo(x, y);
}
function lineEnd() {
stream.point = point;
}
function lineEndPolygon() {
context.closePath();
}
return stream;
}
function d3_geo_resample(project) {
var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16;
function resample(stream) {
return (maxDepth ? resampleRecursive : resampleNone)(stream);
}
function resampleNone(stream) {
return d3_geo_transformPoint(stream, function(x, y) {
x = project(x, y);
stream.point(x[0], x[1]);
});
}
function resampleRecursive(stream) {
var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0;
var resample = {
point: point,
lineStart: lineStart,
lineEnd: lineEnd,
polygonStart: function() {
stream.polygonStart();
resample.lineStart = ringStart;
},
polygonEnd: function() {
stream.polygonEnd();
resample.lineStart = lineStart;
}
};
function point(x, y) {
x = project(x, y);
stream.point(x[0], x[1]);
}
function lineStart() {
x0 = NaN;
resample.point = linePoint;
stream.lineStart();
}
function linePoint(λ, φ) {
var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
stream.point(x0, y0);
}
function lineEnd() {
resample.point = point;
stream.lineEnd();
}
function ringStart() {
lineStart();
resample.point = ringPoint;
resample.lineEnd = ringEnd;
}
function ringPoint(λ, φ) {
linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
resample.point = linePoint;
}
function ringEnd() {
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
resample.lineEnd = lineEnd;
lineEnd();
}
return resample;
}
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy;
if (d2 > 4 * δ2 && depth--) {
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) {
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
stream.point(x2, y2);
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
}
}
}
resample.precision = function(_) {
if (!arguments.length) return Math.sqrt(δ2);
maxDepth = (δ2 = _ * _) > 0 && 16;
return resample;
};
return resample;
}
d3.geo.path = function() {
var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream;
function path(object) {
if (object) {
if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream);
d3.geo.stream(object, cacheStream);
}
return contextStream.result();
}
path.area = function(object) {
d3_geo_pathAreaSum = 0;
d3.geo.stream(object, projectStream(d3_geo_pathArea));
return d3_geo_pathAreaSum;
};
path.centroid = function(object) {
d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;
d3.geo.stream(object, projectStream(d3_geo_pathCentroid));
return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ];
};
path.bounds = function(object) {
d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity);
d3.geo.stream(object, projectStream(d3_geo_pathBounds));
return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ];
};
path.projection = function(_) {
if (!arguments.length) return projection;
projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity;
return reset();
};
path.context = function(_) {
if (!arguments.length) return context;
contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_);
if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
return reset();
};
path.pointRadius = function(_) {
if (!arguments.length) return pointRadius;
pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
return path;
};
function reset() {
cacheStream = null;
return path;
}
return path.projection(d3.geo.albersUsa()).context(null);
};
function d3_geo_pathProjectStream(project) {
var resample = d3_geo_resample(function(x, y) {
return project([ x * d3_degrees, y * d3_degrees ]);
});
return function(stream) {
return d3_geo_projectionRadians(resample(stream));
};
}
d3.geo.transform = function(methods) {
return {
stream: function(stream) {
var transform = new d3_geo_transform(stream);
for (var k in methods) transform[k] = methods[k];
return transform;
}
};
};
function d3_geo_transform(stream) {
this.stream = stream;
}
d3_geo_transform.prototype = {
point: function(x, y) {
this.stream.point(x, y);
},
sphere: function() {
this.stream.sphere();
},
lineStart: function() {
this.stream.lineStart();
},
lineEnd: function() {
this.stream.lineEnd();
},
polygonStart: function() {
this.stream.polygonStart();
},
polygonEnd: function() {
this.stream.polygonEnd();
}
};
function d3_geo_transformPoint(stream, point) {
return {
point: point,
sphere: function() {
stream.sphere();
},
lineStart: function() {
stream.lineStart();
},
lineEnd: function() {
stream.lineEnd();
},
polygonStart: function() {
stream.polygonStart();
},
polygonEnd: function() {
stream.polygonEnd();
}
};
}
d3.geo.projection = d3_geo_projection;
d3.geo.projectionMutator = d3_geo_projectionMutator;
function d3_geo_projection(project) {
return d3_geo_projectionMutator(function() {
return project;
})();
}
function d3_geo_projectionMutator(projectAt) {
var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) {
x = project(x, y);
return [ x[0] * k + δx, δy - x[1] * k ];
}), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream;
function projection(point) {
point = projectRotate(point[0] * d3_radians, point[1] * d3_radians);
return [ point[0] * k + δx, δy - point[1] * k ];
}
function invert(point) {
point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k);
return point && [ point[0] * d3_degrees, point[1] * d3_degrees ];
}
projection.stream = function(output) {
if (stream) stream.valid = false;
stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output))));
stream.valid = true;
return stream;
};
projection.clipAngle = function(_) {
if (!arguments.length) return clipAngle;
preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians);
return invalidate();
};
projection.clipExtent = function(_) {
if (!arguments.length) return clipExtent;
clipExtent = _;
postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity;
return invalidate();
};
projection.scale = function(_) {
if (!arguments.length) return k;
k = +_;
return reset();
};
projection.translate = function(_) {
if (!arguments.length) return [ x, y ];
x = +_[0];
y = +_[1];
return reset();
};
projection.center = function(_) {
if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ];
λ = _[0] % 360 * d3_radians;
φ = _[1] % 360 * d3_radians;
return reset();
};
projection.rotate = function(_) {
if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ];
δλ = _[0] % 360 * d3_radians;
δφ = _[1] % 360 * d3_radians;
δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0;
return reset();
};
d3.rebind(projection, projectResample, "precision");
function reset() {
projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project);
var center = project(λ, φ);
δx = x - center[0] * k;
δy = y + center[1] * k;
return invalidate();
}
function invalidate() {
if (stream) stream.valid = false, stream = null;
return projection;
}
return function() {
project = projectAt.apply(this, arguments);
projection.invert = project.invert && invert;
return reset();
};
}
function d3_geo_projectionRadians(stream) {
return d3_geo_transformPoint(stream, function(x, y) {
stream.point(x * d3_radians, y * d3_radians);
});
}
function d3_geo_equirectangular(λ, φ) {
return [ λ, φ ];
}
(d3.geo.equirectangular = function() {
return d3_geo_projection(d3_geo_equirectangular);
}).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular;
d3.geo.rotation = function(rotate) {
rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0);
function forward(coordinates) {
coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;
}
forward.invert = function(coordinates) {
coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;
};
return forward;
};
function d3_geo_identityRotation(λ, φ) {
return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];
}
d3_geo_identityRotation.invert = d3_geo_equirectangular;
function d3_geo_rotation(δλ, δφ, δγ) {
return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation;
}
function d3_geo_forwardRotationλ(δλ) {
return function(λ, φ) {
return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];
};
}
function d3_geo_rotationλ(δλ) {
var rotation = d3_geo_forwardRotationλ(δλ);
rotation.invert = d3_geo_forwardRotationλ(-δλ);
return rotation;
}
function d3_geo_rotationφγ(δφ, δγ) {
var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ);
function rotation(λ, φ) {
var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ;
return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ];
}
rotation.invert = function(λ, φ) {
var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ;
return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ];
};
return rotation;
}
d3.geo.circle = function() {
var origin = [ 0, 0 ], angle, precision = 6, interpolate;
function circle() {
var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = [];
interpolate(null, null, 1, {
point: function(x, y) {
ring.push(x = rotate(x, y));
x[0] *= d3_degrees, x[1] *= d3_degrees;
}
});
return {
type: "Polygon",
coordinates: [ ring ]
};
}
circle.origin = function(x) {
if (!arguments.length) return origin;
origin = x;
return circle;
};
circle.angle = function(x) {
if (!arguments.length) return angle;
interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians);
return circle;
};
circle.precision = function(_) {
if (!arguments.length) return precision;
interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians);
return circle;
};
return circle.angle(90);
};
function d3_geo_circleInterpolate(radius, precision) {
var cr = Math.cos(radius), sr = Math.sin(radius);
return function(from, to, direction, listener) {
var step = direction * precision;
if (from != null) {
from = d3_geo_circleAngle(cr, from);
to = d3_geo_circleAngle(cr, to);
if (direction > 0 ? from < to : from > to) from += direction * τ;
} else {
from = radius + direction * τ;
to = radius - .5 * step;
}
for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) {
listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]);
}
};
}
function d3_geo_circleAngle(cr, point) {
var a = d3_geo_cartesian(point);
a[0] -= cr;
d3_geo_cartesianNormalize(a);
var angle = d3_acos(-a[1]);
return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI);
}
d3.geo.distance = function(a, b) {
var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t;
return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ);
};
d3.geo.graticule = function() {
var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5;
function graticule() {
return {
type: "MultiLineString",
coordinates: lines()
};
}
function lines() {
return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) {
return abs(x % DX) > ε;
}).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) {
return abs(y % DY) > ε;
}).map(y));
}
graticule.lines = function() {
return lines().map(function(coordinates) {
return {
type: "LineString",
coordinates: coordinates
};
});
};
graticule.outline = function() {
return {
type: "Polygon",
coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ]
};
};
graticule.extent = function(_) {
if (!arguments.length) return graticule.minorExtent();
return graticule.majorExtent(_).minorExtent(_);
};
graticule.majorExtent = function(_) {
if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ];
X0 = +_[0][0], X1 = +_[1][0];
Y0 = +_[0][1], Y1 = +_[1][1];
if (X0 > X1) _ = X0, X0 = X1, X1 = _;
if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
return graticule.precision(precision);
};
graticule.minorExtent = function(_) {
if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];
x0 = +_[0][0], x1 = +_[1][0];
y0 = +_[0][1], y1 = +_[1][1];
if (x0 > x1) _ = x0, x0 = x1, x1 = _;
if (y0 > y1) _ = y0, y0 = y1, y1 = _;
return graticule.precision(precision);
};
graticule.step = function(_) {
if (!arguments.length) return graticule.minorStep();
return graticule.majorStep(_).minorStep(_);
};
graticule.majorStep = function(_) {
if (!arguments.length) return [ DX, DY ];
DX = +_[0], DY = +_[1];
return graticule;
};
graticule.minorStep = function(_) {
if (!arguments.length) return [ dx, dy ];
dx = +_[0], dy = +_[1];
return graticule;
};
graticule.precision = function(_) {
if (!arguments.length) return precision;
precision = +_;
x = d3_geo_graticuleX(y0, y1, 90);
y = d3_geo_graticuleY(x0, x1, precision);
X = d3_geo_graticuleX(Y0, Y1, 90);
Y = d3_geo_graticuleY(X0, X1, precision);
return graticule;
};
return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]);
};
function d3_geo_graticuleX(y0, y1, dy) {
var y = d3.range(y0, y1 - ε, dy).concat(y1);
return function(x) {
return y.map(function(y) {
return [ x, y ];
});
};
}
function d3_geo_graticuleY(x0, x1, dx) {
var x = d3.range(x0, x1 - ε, dx).concat(x1);
return function(y) {
return x.map(function(x) {
return [ x, y ];
});
};
}
function d3_source(d) {
return d.source;
}
function d3_target(d) {
return d.target;
}
d3.geo.greatArc = function() {
var source = d3_source, source_, target = d3_target, target_;
function greatArc() {
return {
type: "LineString",
coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ]
};
}
greatArc.distance = function() {
return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments));
};
greatArc.source = function(_) {
if (!arguments.length) return source;
source = _, source_ = typeof _ === "function" ? null : _;
return greatArc;
};
greatArc.target = function(_) {
if (!arguments.length) return target;
target = _, target_ = typeof _ === "function" ? null : _;
return greatArc;
};
greatArc.precision = function() {
return arguments.length ? greatArc : 0;
};
return greatArc;
};
d3.geo.interpolate = function(source, target) {
return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians);
};
function d3_geo_interpolate(x0, y0, x1, y1) {
var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d);
var interpolate = d ? function(t) {
var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;
return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ];
} : function() {
return [ x0 * d3_degrees, y0 * d3_degrees ];
};
interpolate.distance = d;
return interpolate;
}
d3.geo.length = function(object) {
d3_geo_lengthSum = 0;
d3.geo.stream(object, d3_geo_length);
return d3_geo_lengthSum;
};
var d3_geo_lengthSum;
var d3_geo_length = {
sphere: d3_noop,
point: d3_noop,
lineStart: d3_geo_lengthLineStart,
lineEnd: d3_noop,
polygonStart: d3_noop,
polygonEnd: d3_noop
};
function d3_geo_lengthLineStart() {
var λ0, sinφ0, cosφ0;
d3_geo_length.point = function(λ, φ) {
λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ);
d3_geo_length.point = nextPoint;
};
d3_geo_length.lineEnd = function() {
d3_geo_length.point = d3_geo_length.lineEnd = d3_noop;
};
function nextPoint(λ, φ) {
var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t);
d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ);
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;
}
}
function d3_geo_azimuthal(scale, angle) {
function azimuthal(λ, φ) {
var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ);
return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ];
}
azimuthal.invert = function(x, y) {
var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c);
return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ];
};
return azimuthal;
}
var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) {
return Math.sqrt(2 / (1 + cosλcosφ));
}, function(ρ) {
return 2 * Math.asin(ρ / 2);
});
(d3.geo.azimuthalEqualArea = function() {
return d3_geo_projection(d3_geo_azimuthalEqualArea);
}).raw = d3_geo_azimuthalEqualArea;
var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) {
var c = Math.acos(cosλcosφ);
return c && c / Math.sin(c);
}, d3_identity);
(d3.geo.azimuthalEquidistant = function() {
return d3_geo_projection(d3_geo_azimuthalEquidistant);
}).raw = d3_geo_azimuthalEquidistant;
function d3_geo_conicConformal(φ0, φ1) {
var cosφ0 = Math.cos(φ0), t = function(φ) {
return Math.tan(π / 4 + φ / 2);
}, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n;
if (!n) return d3_geo_mercator;
function forward(λ, φ) {
if (F > 0) {
if (φ < -halfπ + ε) φ = -halfπ + ε;
} else {
if (φ > halfπ - ε) φ = halfπ - ε;
}
var ρ = F / Math.pow(t(φ), n);
return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ];
}
forward.invert = function(x, y) {
var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y);
return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ];
};
return forward;
}
(d3.geo.conicConformal = function() {
return d3_geo_conic(d3_geo_conicConformal);
}).raw = d3_geo_conicConformal;
function d3_geo_conicEquidistant(φ0, φ1) {
var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0;
if (abs(n) < ε) return d3_geo_equirectangular;
function forward(λ, φ) {
var ρ = G - φ;
return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ];
}
forward.invert = function(x, y) {
var ρ0_y = G - y;
return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ];
};
return forward;
}
(d3.geo.conicEquidistant = function() {
return d3_geo_conic(d3_geo_conicEquidistant);
}).raw = d3_geo_conicEquidistant;
var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) {
return 1 / cosλcosφ;
}, Math.atan);
(d3.geo.gnomonic = function() {
return d3_geo_projection(d3_geo_gnomonic);
}).raw = d3_geo_gnomonic;
function d3_geo_mercator(λ, φ) {
return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ];
}
d3_geo_mercator.invert = function(x, y) {
return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ];
};
function d3_geo_mercatorProjection(project) {
var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto;
m.scale = function() {
var v = scale.apply(m, arguments);
return v === m ? clipAuto ? m.clipExtent(null) : m : v;
};
m.translate = function() {
var v = translate.apply(m, arguments);
return v === m ? clipAuto ? m.clipExtent(null) : m : v;
};
m.clipExtent = function(_) {
var v = clipExtent.apply(m, arguments);
if (v === m) {
if (clipAuto = _ == null) {
var k = π * scale(), t = translate();
clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]);
}
} else if (clipAuto) {
v = null;
}
return v;
};
return m.clipExtent(null);
}
(d3.geo.mercator = function() {
return d3_geo_mercatorProjection(d3_geo_mercator);
}).raw = d3_geo_mercator;
var d3_geo_orthographic = d3_geo_azimuthal(function() {
return 1;
}, Math.asin);
(d3.geo.orthographic = function() {
return d3_geo_projection(d3_geo_orthographic);
}).raw = d3_geo_orthographic;
var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) {
return 1 / (1 + cosλcosφ);
}, function(ρ) {
return 2 * Math.atan(ρ);
});
(d3.geo.stereographic = function() {
return d3_geo_projection(d3_geo_stereographic);
}).raw = d3_geo_stereographic;
function d3_geo_transverseMercator(λ, φ) {
return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ];
}
d3_geo_transverseMercator.invert = function(x, y) {
return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ];
};
(d3.geo.transverseMercator = function() {
var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate;
projection.center = function(_) {
return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]);
};
projection.rotate = function(_) {
return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(),
[ _[0], _[1], _[2] - 90 ]);
};
return rotate([ 0, 0, 90 ]);
}).raw = d3_geo_transverseMercator;
d3.geom = {};
function d3_geom_pointX(d) {
return d[0];
}
function d3_geom_pointY(d) {
return d[1];
}
d3.geom.hull = function(vertices) {
var x = d3_geom_pointX, y = d3_geom_pointY;
if (arguments.length) return hull(vertices);
function hull(data) {
if (data.length < 3) return [];
var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = [];
for (i = 0; i < n; i++) {
points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]);
}
points.sort(d3_geom_hullOrder);
for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]);
var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints);
var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = [];
for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]);
for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]);
return polygon;
}
hull.x = function(_) {
return arguments.length ? (x = _, hull) : x;
};
hull.y = function(_) {
return arguments.length ? (y = _, hull) : y;
};
return hull;
};
function d3_geom_hullUpper(points) {
var n = points.length, hull = [ 0, 1 ], hs = 2;
for (var i = 2; i < n; i++) {
while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs;
hull[hs++] = i;
}
return hull.slice(0, hs);
}
function d3_geom_hullOrder(a, b) {
return a[0] - b[0] || a[1] - b[1];
}
d3.geom.polygon = function(coordinates) {
d3_subclass(coordinates, d3_geom_polygonPrototype);
return coordinates;
};
var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];
d3_geom_polygonPrototype.area = function() {
var i = -1, n = this.length, a, b = this[n - 1], area = 0;
while (++i < n) {
a = b;
b = this[i];
area += a[1] * b[0] - a[0] * b[1];
}
return area * .5;
};
d3_geom_polygonPrototype.centroid = function(k) {
var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c;
if (!arguments.length) k = -1 / (6 * this.area());
while (++i < n) {
a = b;
b = this[i];
c = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * c;
y += (a[1] + b[1]) * c;
}
return [ x * k, y * k ];
};
d3_geom_polygonPrototype.clip = function(subject) {
var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d;
while (++i < n) {
input = subject.slice();
subject.length = 0;
b = this[i];
c = input[(m = input.length - closed) - 1];
j = -1;
while (++j < m) {
d = input[j];
if (d3_geom_polygonInside(d, a, b)) {
if (!d3_geom_polygonInside(c, a, b)) {
subject.push(d3_geom_polygonIntersect(c, d, a, b));
}
subject.push(d);
} else if (d3_geom_polygonInside(c, a, b)) {
subject.push(d3_geom_polygonIntersect(c, d, a, b));
}
c = d;
}
if (closed) subject.push(subject[0]);
a = b;
}
return subject;
};
function d3_geom_polygonInside(p, a, b) {
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
}
function d3_geom_polygonIntersect(c, d, a, b) {
var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
return [ x1 + ua * x21, y1 + ua * y21 ];
}
function d3_geom_polygonClosed(coordinates) {
var a = coordinates[0], b = coordinates[coordinates.length - 1];
return !(a[0] - b[0] || a[1] - b[1]);
}
var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = [];
function d3_geom_voronoiBeach() {
d3_geom_voronoiRedBlackNode(this);
this.edge = this.site = this.circle = null;
}
function d3_geom_voronoiCreateBeach(site) {
var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach();
beach.site = site;
return beach;
}
function d3_geom_voronoiDetachBeach(beach) {
d3_geom_voronoiDetachCircle(beach);
d3_geom_voronoiBeaches.remove(beach);
d3_geom_voronoiBeachPool.push(beach);
d3_geom_voronoiRedBlackNode(beach);
}
function d3_geom_voronoiRemoveBeach(beach) {
var circle = beach.circle, x = circle.x, y = circle.cy, vertex = {
x: x,
y: y
}, previous = beach.P, next = beach.N, disappearing = [ beach ];
d3_geom_voronoiDetachBeach(beach);
var lArc = previous;
while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) {
previous = lArc.P;
disappearing.unshift(lArc);
d3_geom_voronoiDetachBeach(lArc);
lArc = previous;
}
disappearing.unshift(lArc);
d3_geom_voronoiDetachCircle(lArc);
var rArc = next;
while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) {
next = rArc.N;
disappearing.push(rArc);
d3_geom_voronoiDetachBeach(rArc);
rArc = next;
}
disappearing.push(rArc);
d3_geom_voronoiDetachCircle(rArc);
var nArcs = disappearing.length, iArc;
for (iArc = 1; iArc < nArcs; ++iArc) {
rArc = disappearing[iArc];
lArc = disappearing[iArc - 1];
d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
}
lArc = disappearing[0];
rArc = disappearing[nArcs - 1];
rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex);
d3_geom_voronoiAttachCircle(lArc);
d3_geom_voronoiAttachCircle(rArc);
}
function d3_geom_voronoiAddBeach(site) {
var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._;
while (node) {
dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x;
if (dxl > ε) node = node.L; else {
dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix);
if (dxr > ε) {
if (!node.R) {
lArc = node;
break;
}
node = node.R;
} else {
if (dxl > -ε) {
lArc = node.P;
rArc = node;
} else if (dxr > -ε) {
lArc = node;
rArc = node.N;
} else {
lArc = rArc = node;
}
break;
}
}
}
var newArc = d3_geom_voronoiCreateBeach(site);
d3_geom_voronoiBeaches.insert(lArc, newArc);
if (!lArc && !rArc) return;
if (lArc === rArc) {
d3_geom_voronoiDetachCircle(lArc);
rArc = d3_geom_voronoiCreateBeach(lArc.site);
d3_geom_voronoiBeaches.insert(newArc, rArc);
newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);
d3_geom_voronoiAttachCircle(lArc);
d3_geom_voronoiAttachCircle(rArc);
return;
}
if (!rArc) {
newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);
return;
}
d3_geom_voronoiDetachCircle(lArc);
d3_geom_voronoiDetachCircle(rArc);
var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = {
x: (cy * hb - by * hc) / d + ax,
y: (bx * hc - cx * hb) / d + ay
};
d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex);
newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex);
rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex);
d3_geom_voronoiAttachCircle(lArc);
d3_geom_voronoiAttachCircle(rArc);
}
function d3_geom_voronoiLeftBreakPoint(arc, directrix) {
var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix;
if (!pby2) return rfocx;
var lArc = arc.P;
if (!lArc) return -Infinity;
site = lArc.site;
var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix;
if (!plby2) return lfocx;
var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2;
if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
return (rfocx + lfocx) / 2;
}
function d3_geom_voronoiRightBreakPoint(arc, directrix) {
var rArc = arc.N;
if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix);
var site = arc.site;
return site.y === directrix ? site.x : Infinity;
}
function d3_geom_voronoiCell(site) {
this.site = site;
this.edges = [];
}
d3_geom_voronoiCell.prototype.prepare = function() {
var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge;
while (iHalfEdge--) {
edge = halfEdges[iHalfEdge].edge;
if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1);
}
halfEdges.sort(d3_geom_voronoiHalfEdgeOrder);
return halfEdges.length;
};
function d3_geom_voronoiCloseCells(extent) {
var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end;
while (iCell--) {
cell = cells[iCell];
if (!cell || !cell.prepare()) continue;
halfEdges = cell.edges;
nHalfEdges = halfEdges.length;
iHalfEdge = 0;
while (iHalfEdge < nHalfEdges) {
end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y;
start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y;
if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) {
halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? {
x: x0,
y: abs(x2 - x0) < ε ? y2 : y1
} : abs(y3 - y1) < ε && x1 - x3 > ε ? {
x: abs(y2 - y1) < ε ? x2 : x1,
y: y1
} : abs(x3 - x1) < ε && y3 - y0 > ε ? {
x: x1,
y: abs(x2 - x1) < ε ? y2 : y0
} : abs(y3 - y0) < ε && x3 - x0 > ε ? {
x: abs(y2 - y0) < ε ? x2 : x0,
y: y0
} : null), cell.site, null));
++nHalfEdges;
}
}
}
}
function d3_geom_voronoiHalfEdgeOrder(a, b) {
return b.angle - a.angle;
}
function d3_geom_voronoiCircle() {
d3_geom_voronoiRedBlackNode(this);
this.x = this.y = this.arc = this.site = this.cy = null;
}
function d3_geom_voronoiAttachCircle(arc) {
var lArc = arc.P, rArc = arc.N;
if (!lArc || !rArc) return;
var lSite = lArc.site, cSite = arc.site, rSite = rArc.site;
if (lSite === rSite) return;
var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by;
var d = 2 * (ax * cy - ay * cx);
if (d >= -ε2) return;
var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by;
var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle();
circle.arc = arc;
circle.site = cSite;
circle.x = x + bx;
circle.y = cy + Math.sqrt(x * x + y * y);
circle.cy = cy;
arc.circle = circle;
var before = null, node = d3_geom_voronoiCircles._;
while (node) {
if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) {
if (node.L) node = node.L; else {
before = node.P;
break;
}
} else {
if (node.R) node = node.R; else {
before = node;
break;
}
}
}
d3_geom_voronoiCircles.insert(before, circle);
if (!before) d3_geom_voronoiFirstCircle = circle;
}
function d3_geom_voronoiDetachCircle(arc) {
var circle = arc.circle;
if (circle) {
if (!circle.P) d3_geom_voronoiFirstCircle = circle.N;
d3_geom_voronoiCircles.remove(circle);
d3_geom_voronoiCirclePool.push(circle);
d3_geom_voronoiRedBlackNode(circle);
arc.circle = null;
}
}
function d3_geom_voronoiClipEdges(extent) {
var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e;
while (i--) {
e = edges[i];
if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) {
e.a = e.b = null;
edges.splice(i, 1);
}
}
}
function d3_geom_voronoiConnectEdge(edge, extent) {
var vb = edge.b;
if (vb) return true;
var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb;
if (ry === ly) {
if (fx < x0 || fx >= x1) return;
if (lx > rx) {
if (!va) va = {
x: fx,
y: y0
}; else if (va.y >= y1) return;
vb = {
x: fx,
y: y1
};
} else {
if (!va) va = {
x: fx,
y: y1
}; else if (va.y < y0) return;
vb = {
x: fx,
y: y0
};
}
} else {
fm = (lx - rx) / (ry - ly);
fb = fy - fm * fx;
if (fm < -1 || fm > 1) {
if (lx > rx) {
if (!va) va = {
x: (y0 - fb) / fm,
y: y0
}; else if (va.y >= y1) return;
vb = {
x: (y1 - fb) / fm,
y: y1
};
} else {
if (!va) va = {
x: (y1 - fb) / fm,
y: y1
}; else if (va.y < y0) return;
vb = {
x: (y0 - fb) / fm,
y: y0
};
}
} else {
if (ly < ry) {
if (!va) va = {
x: x0,
y: fm * x0 + fb
}; else if (va.x >= x1) return;
vb = {
x: x1,
y: fm * x1 + fb
};
} else {
if (!va) va = {
x: x1,
y: fm * x1 + fb
}; else if (va.x < x0) return;
vb = {
x: x0,
y: fm * x0 + fb
};
}
}
}
edge.a = va;
edge.b = vb;
return true;
}
function d3_geom_voronoiEdge(lSite, rSite) {
this.l = lSite;
this.r = rSite;
this.a = this.b = null;
}
function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) {
var edge = new d3_geom_voronoiEdge(lSite, rSite);
d3_geom_voronoiEdges.push(edge);
if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va);
if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb);
d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite));
d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite));
return edge;
}
function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) {
var edge = new d3_geom_voronoiEdge(lSite, null);
edge.a = va;
edge.b = vb;
d3_geom_voronoiEdges.push(edge);
return edge;
}
function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) {
if (!edge.a && !edge.b) {
edge.a = vertex;
edge.l = lSite;
edge.r = rSite;
} else if (edge.l === rSite) {
edge.b = vertex;
} else {
edge.a = vertex;
}
}
function d3_geom_voronoiHalfEdge(edge, lSite, rSite) {
var va = edge.a, vb = edge.b;
this.edge = edge;
this.site = lSite;
this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y);
}
d3_geom_voronoiHalfEdge.prototype = {
start: function() {
return this.edge.l === this.site ? this.edge.a : this.edge.b;
},
end: function() {
return this.edge.l === this.site ? this.edge.b : this.edge.a;
}
};
function d3_geom_voronoiRedBlackTree() {
this._ = null;
}
function d3_geom_voronoiRedBlackNode(node) {
node.U = node.C = node.L = node.R = node.P = node.N = null;
}
d3_geom_voronoiRedBlackTree.prototype = {
insert: function(after, node) {
var parent, grandpa, uncle;
if (after) {
node.P = after;
node.N = after.N;
if (after.N) after.N.P = node;
after.N = node;
if (after.R) {
after = after.R;
while (after.L) after = after.L;
after.L = node;
} else {
after.R = node;
}
parent = after;
} else if (this._) {
after = d3_geom_voronoiRedBlackFirst(this._);
node.P = null;
node.N = after;
after.P = after.L = node;
parent = after;
} else {
node.P = node.N = null;
this._ = node;
parent = null;
}
node.L = node.R = null;
node.U = parent;
node.C = true;
after = node;
while (parent && parent.C) {
grandpa = parent.U;
if (parent === grandpa.L) {
uncle = grandpa.R;
if (uncle && uncle.C) {
parent.C = uncle.C = false;
grandpa.C = true;
after = grandpa;
} else {
if (after === parent.R) {
d3_geom_voronoiRedBlackRotateLeft(this, parent);
after = parent;
parent = after.U;
}
parent.C = false;
grandpa.C = true;
d3_geom_voronoiRedBlackRotateRight(this, grandpa);
}
} else {
uncle = grandpa.L;
if (uncle && uncle.C) {
parent.C = uncle.C = false;
grandpa.C = true;
after = grandpa;
} else {
if (after === parent.L) {
d3_geom_voronoiRedBlackRotateRight(this, parent);
after = parent;
parent = after.U;
}
parent.C = false;
grandpa.C = true;
d3_geom_voronoiRedBlackRotateLeft(this, grandpa);
}
}
parent = after.U;
}
this._.C = false;
},
remove: function(node) {
if (node.N) node.N.P = node.P;
if (node.P) node.P.N = node.N;
node.N = node.P = null;
var parent = node.U, sibling, left = node.L, right = node.R, next, red;
if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right);
if (parent) {
if (parent.L === node) parent.L = next; else parent.R = next;
} else {
this._ = next;
}
if (left && right) {
red = next.C;
next.C = node.C;
next.L = left;
left.U = next;
if (next !== right) {
parent = next.U;
next.U = node.U;
node = next.R;
parent.L = node;
next.R = right;
right.U = next;
} else {
next.U = parent;
parent = next;
node = next.R;
}
} else {
red = node.C;
node = next;
}
if (node) node.U = parent;
if (red) return;
if (node && node.C) {
node.C = false;
return;
}
do {
if (node === this._) break;
if (node === parent.L) {
sibling = parent.R;
if (sibling.C) {
sibling.C = false;
parent.C = true;
d3_geom_voronoiRedBlackRotateLeft(this, parent);
sibling = parent.R;
}
if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {
if (!sibling.R || !sibling.R.C) {
sibling.L.C = false;
sibling.C = true;
d3_geom_voronoiRedBlackRotateRight(this, sibling);
sibling = parent.R;
}
sibling.C = parent.C;
parent.C = sibling.R.C = false;
d3_geom_voronoiRedBlackRotateLeft(this, parent);
node = this._;
break;
}
} else {
sibling = parent.L;
if (sibling.C) {
sibling.C = false;
parent.C = true;
d3_geom_voronoiRedBlackRotateRight(this, parent);
sibling = parent.L;
}
if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {
if (!sibling.L || !sibling.L.C) {
sibling.R.C = false;
sibling.C = true;
d3_geom_voronoiRedBlackRotateLeft(this, sibling);
sibling = parent.L;
}
sibling.C = parent.C;
parent.C = sibling.L.C = false;
d3_geom_voronoiRedBlackRotateRight(this, parent);
node = this._;
break;
}
}
sibling.C = true;
node = parent;
parent = parent.U;
} while (!node.C);
if (node) node.C = false;
}
};
function d3_geom_voronoiRedBlackRotateLeft(tree, node) {
var p = node, q = node.R, parent = p.U;
if (parent) {
if (parent.L === p) parent.L = q; else parent.R = q;
} else {
tree._ = q;
}
q.U = parent;
p.U = q;
p.R = q.L;
if (p.R) p.R.U = p;
q.L = p;
}
function d3_geom_voronoiRedBlackRotateRight(tree, node) {
var p = node, q = node.L, parent = p.U;
if (parent) {
if (parent.L === p) parent.L = q; else parent.R = q;
} else {
tree._ = q;
}
q.U = parent;
p.U = q;
p.L = q.R;
if (p.L) p.L.U = p;
q.R = p;
}
function d3_geom_voronoiRedBlackFirst(node) {
while (node.L) node = node.L;
return node;
}
function d3_geom_voronoi(sites, bbox) {
var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle;
d3_geom_voronoiEdges = [];
d3_geom_voronoiCells = new Array(sites.length);
d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree();
d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree();
while (true) {
circle = d3_geom_voronoiFirstCircle;
if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) {
if (site.x !== x0 || site.y !== y0) {
d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site);
d3_geom_voronoiAddBeach(site);
x0 = site.x, y0 = site.y;
}
site = sites.pop();
} else if (circle) {
d3_geom_voronoiRemoveBeach(circle.arc);
} else {
break;
}
}
if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox);
var diagram = {
cells: d3_geom_voronoiCells,
edges: d3_geom_voronoiEdges
};
d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null;
return diagram;
}
function d3_geom_voronoiVertexOrder(a, b) {
return b.y - a.y || b.x - a.x;
}
d3.geom.voronoi = function(points) {
var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent;
if (points) return voronoi(points);
function voronoi(data) {
var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1];
d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) {
var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) {
var s = e.start();
return [ s.x, s.y ];
}) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : [];
polygon.point = data[i];
});
return polygons;
}
function sites(data) {
return data.map(function(d, i) {
return {
x: Math.round(fx(d, i) / ε) * ε,
y: Math.round(fy(d, i) / ε) * ε,
i: i
};
});
}
voronoi.links = function(data) {
return d3_geom_voronoi(sites(data)).edges.filter(function(edge) {
return edge.l && edge.r;
}).map(function(edge) {
return {
source: data[edge.l.i],
target: data[edge.r.i]
};
});
};
voronoi.triangles = function(data) {
var triangles = [];
d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) {
var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l;
while (++j < m) {
e0 = e1;
s0 = s1;
e1 = edges[j].edge;
s1 = e1.l === site ? e1.r : e1.l;
if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) {
triangles.push([ data[i], data[s0.i], data[s1.i] ]);
}
}
});
return triangles;
};
voronoi.x = function(_) {
return arguments.length ? (fx = d3_functor(x = _), voronoi) : x;
};
voronoi.y = function(_) {
return arguments.length ? (fy = d3_functor(y = _), voronoi) : y;
};
voronoi.clipExtent = function(_) {
if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent;
clipExtent = _ == null ? d3_geom_voronoiClipExtent : _;
return voronoi;
};
voronoi.size = function(_) {
if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1];
return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]);
};
return voronoi;
};
var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ];
function d3_geom_voronoiTriangleArea(a, b, c) {
return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y);
}
d3.geom.delaunay = function(vertices) {
return d3.geom.voronoi().triangles(vertices);
};
d3.geom.quadtree = function(points, x1, y1, x2, y2) {
var x = d3_geom_pointX, y = d3_geom_pointY, compat;
if (compat = arguments.length) {
x = d3_geom_quadtreeCompatX;
y = d3_geom_quadtreeCompatY;
if (compat === 3) {
y2 = y1;
x2 = x1;
y1 = x1 = 0;
}
return quadtree(points);
}
function quadtree(data) {
var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_;
if (x1 != null) {
x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2;
} else {
x2_ = y2_ = -(x1_ = y1_ = Infinity);
xs = [], ys = [];
n = data.length;
if (compat) for (i = 0; i < n; ++i) {
d = data[i];
if (d.x < x1_) x1_ = d.x;
if (d.y < y1_) y1_ = d.y;
if (d.x > x2_) x2_ = d.x;
if (d.y > y2_) y2_ = d.y;
xs.push(d.x);
ys.push(d.y);
} else for (i = 0; i < n; ++i) {
var x_ = +fx(d = data[i], i), y_ = +fy(d, i);
if (x_ < x1_) x1_ = x_;
if (y_ < y1_) y1_ = y_;
if (x_ > x2_) x2_ = x_;
if (y_ > y2_) y2_ = y_;
xs.push(x_);
ys.push(y_);
}
}
var dx = x2_ - x1_, dy = y2_ - y1_;
if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy;
function insert(n, d, x, y, x1, y1, x2, y2) {
if (isNaN(x) || isNaN(y)) return;
if (n.leaf) {
var nx = n.x, ny = n.y;
if (nx != null) {
if (abs(nx - x) + abs(ny - y) < .01) {
insertChild(n, d, x, y, x1, y1, x2, y2);
} else {
var nPoint = n.point;
n.x = n.y = n.point = null;
insertChild(n, nPoint, nx, ny, x1, y1, x2, y2);
insertChild(n, d, x, y, x1, y1, x2, y2);
}
} else {
n.x = x, n.y = y, n.point = d;
}
} else {
insertChild(n, d, x, y, x1, y1, x2, y2);
}
}
function insertChild(n, d, x, y, x1, y1, x2, y2) {
var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right;
n.leaf = false;
n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());
if (right) x1 = sx; else x2 = sx;
if (bottom) y1 = sy; else y2 = sy;
insert(n, d, x, y, x1, y1, x2, y2);
}
var root = d3_geom_quadtreeNode();
root.add = function(d) {
insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_);
};
root.visit = function(f) {
d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_);
};
i = -1;
if (x1 == null) {
while (++i < n) {
insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_);
}
--i;
} else data.forEach(root.add);
xs = ys = data = d = null;
return root;
}
quadtree.x = function(_) {
return arguments.length ? (x = _, quadtree) : x;
};
quadtree.y = function(_) {
return arguments.length ? (y = _, quadtree) : y;
};
quadtree.extent = function(_) {
if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ];
if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0],
y2 = +_[1][1];
return quadtree;
};
quadtree.size = function(_) {
if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ];
if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1];
return quadtree;
};
return quadtree;
};
function d3_geom_quadtreeCompatX(d) {
return d.x;
}
function d3_geom_quadtreeCompatY(d) {
return d.y;
}
function d3_geom_quadtreeNode() {
return {
leaf: true,
nodes: [],
point: null,
x: null,
y: null
};
}
function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
if (!f(node, x1, y1, x2, y2)) {
var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes;
if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
}
}
d3.interpolateRgb = d3_interpolateRgb;
function d3_interpolateRgb(a, b) {
a = d3.rgb(a);
b = d3.rgb(b);
var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab;
return function(t) {
return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t));
};
}
d3.interpolateObject = d3_interpolateObject;
function d3_interpolateObject(a, b) {
var i = {}, c = {}, k;
for (k in a) {
if (k in b) {
i[k] = d3_interpolate(a[k], b[k]);
} else {
c[k] = a[k];
}
}
for (k in b) {
if (!(k in a)) {
c[k] = b[k];
}
}
return function(t) {
for (k in i) c[k] = i[k](t);
return c;
};
}
d3.interpolateNumber = d3_interpolateNumber;
function d3_interpolateNumber(a, b) {
b -= a = +a;
return function(t) {
return a + b * t;
};
}
d3.interpolateString = d3_interpolateString;
function d3_interpolateString(a, b) {
var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = [];
a = a + "", b = b + "";
while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) {
if ((bs = bm.index) > bi) {
bs = b.substring(bi, bs);
if (s[i]) s[i] += bs; else s[++i] = bs;
}
if ((am = am[0]) === (bm = bm[0])) {
if (s[i]) s[i] += bm; else s[++i] = bm;
} else {
s[++i] = null;
q.push({
i: i,
x: d3_interpolateNumber(am, bm)
});
}
bi = d3_interpolate_numberB.lastIndex;
}
if (bi < b.length) {
bs = b.substring(bi);
if (s[i]) s[i] += bs; else s[++i] = bs;
}
return s.length < 2 ? q[0] ? (b = q[0].x, function(t) {
return b(t) + "";
}) : function() {
return b;
} : (b = q.length, function(t) {
for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
return s.join("");
});
}
var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g");
d3.interpolate = d3_interpolate;
function d3_interpolate(a, b) {
var i = d3.interpolators.length, f;
while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ;
return f;
}
d3.interpolators = [ function(a, b) {
var t = typeof b;
return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b);
} ];
d3.interpolateArray = d3_interpolateArray;
function d3_interpolateArray(a, b) {
var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i;
for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i]));
for (;i < na; ++i) c[i] = a[i];
for (;i < nb; ++i) c[i] = b[i];
return function(t) {
for (i = 0; i < n0; ++i) c[i] = x[i](t);
return c;
};
}
var d3_ease_default = function() {
return d3_identity;
};
var d3_ease = d3.map({
linear: d3_ease_default,
poly: d3_ease_poly,
quad: function() {
return d3_ease_quad;
},
cubic: function() {
return d3_ease_cubic;
},
sin: function() {
return d3_ease_sin;
},
exp: function() {
return d3_ease_exp;
},
circle: function() {
return d3_ease_circle;
},
elastic: d3_ease_elastic,
back: d3_ease_back,
bounce: function() {
return d3_ease_bounce;
}
});
var d3_ease_mode = d3.map({
"in": d3_identity,
out: d3_ease_reverse,
"in-out": d3_ease_reflect,
"out-in": function(f) {
return d3_ease_reflect(d3_ease_reverse(f));
}
});
d3.ease = function(name) {
var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in";
t = d3_ease.get(t) || d3_ease_default;
m = d3_ease_mode.get(m) || d3_identity;
return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1))));
};
function d3_ease_clamp(f) {
return function(t) {
return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
};
}
function d3_ease_reverse(f) {
return function(t) {
return 1 - f(1 - t);
};
}
function d3_ease_reflect(f) {
return function(t) {
return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));
};
}
function d3_ease_quad(t) {
return t * t;
}
function d3_ease_cubic(t) {
return t * t * t;
}
function d3_ease_cubicInOut(t) {
if (t <= 0) return 0;
if (t >= 1) return 1;
var t2 = t * t, t3 = t2 * t;
return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75);
}
function d3_ease_poly(e) {
return function(t) {
return Math.pow(t, e);
};
}
function d3_ease_sin(t) {
return 1 - Math.cos(t * halfπ);
}
function d3_ease_exp(t) {
return Math.pow(2, 10 * (t - 1));
}
function d3_ease_circle(t) {
return 1 - Math.sqrt(1 - t * t);
}
function d3_ease_elastic(a, p) {
var s;
if (arguments.length < 2) p = .45;
if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4;
return function(t) {
return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p);
};
}
function d3_ease_back(s) {
if (!s) s = 1.70158;
return function(t) {
return t * t * ((s + 1) * t - s);
};
}
function d3_ease_bounce(t) {
return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
}
d3.interpolateHcl = d3_interpolateHcl;
function d3_interpolateHcl(a, b) {
a = d3.hcl(a);
b = d3.hcl(b);
var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al;
if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac;
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
return function(t) {
return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + "";
};
}
d3.interpolateHsl = d3_interpolateHsl;
function d3_interpolateHsl(a, b) {
a = d3.hsl(a);
b = d3.hsl(b);
var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al;
if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as;
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
return function(t) {
return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + "";
};
}
d3.interpolateLab = d3_interpolateLab;
function d3_interpolateLab(a, b) {
a = d3.lab(a);
b = d3.lab(b);
var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab;
return function(t) {
return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + "";
};
}
d3.interpolateRound = d3_interpolateRound;
function d3_interpolateRound(a, b) {
b -= a;
return function(t) {
return Math.round(a + b * t);
};
}
d3.transform = function(string) {
var g = d3_document.createElementNS(d3.ns.prefix.svg, "g");
return (d3.transform = function(string) {
if (string != null) {
g.setAttribute("transform", string);
var t = g.transform.baseVal.consolidate();
}
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};
function d3_transform(m) {
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
if (r0[0] * r1[1] < r1[0] * r0[1]) {
r0[0] *= -1;
r0[1] *= -1;
kx *= -1;
kz *= -1;
}
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees;
this.translate = [ m.e, m.f ];
this.scale = [ kx, ky ];
this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0;
}
d3_transform.prototype.toString = function() {
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
};
function d3_transformDot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
function d3_transformNormalize(a) {
var k = Math.sqrt(d3_transformDot(a, a));
if (k) {
a[0] /= k;
a[1] /= k;
}
return k;
}
function d3_transformCombine(a, b, k) {
a[0] += k * b[0];
a[1] += k * b[1];
return a;
}
var d3_transformIdentity = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0
};
d3.interpolateTransform = d3_interpolateTransform;
function d3_interpolateTransform(a, b) {
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale;
if (ta[0] != tb[0] || ta[1] != tb[1]) {
s.push("translate(", null, ",", null, ")");
q.push({
i: 1,
x: d3_interpolateNumber(ta[0], tb[0])
}, {
i: 3,
x: d3_interpolateNumber(ta[1], tb[1])
});
} else if (tb[0] || tb[1]) {
s.push("translate(" + tb + ")");
} else {
s.push("");
}
if (ra != rb) {
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
q.push({
i: s.push(s.pop() + "rotate(", null, ")") - 2,
x: d3_interpolateNumber(ra, rb)
});
} else if (rb) {
s.push(s.pop() + "rotate(" + rb + ")");
}
if (wa != wb) {
q.push({
i: s.push(s.pop() + "skewX(", null, ")") - 2,
x: d3_interpolateNumber(wa, wb)
});
} else if (wb) {
s.push(s.pop() + "skewX(" + wb + ")");
}
if (ka[0] != kb[0] || ka[1] != kb[1]) {
n = s.push(s.pop() + "scale(", null, ",", null, ")");
q.push({
i: n - 4,
x: d3_interpolateNumber(ka[0], kb[0])
}, {
i: n - 2,
x: d3_interpolateNumber(ka[1], kb[1])
});
} else if (kb[0] != 1 || kb[1] != 1) {
s.push(s.pop() + "scale(" + kb + ")");
}
n = q.length;
return function(t) {
var i = -1, o;
while (++i < n) s[(o = q[i]).i] = o.x(t);
return s.join("");
};
}
function d3_uninterpolateNumber(a, b) {
b = b - (a = +a) ? 1 / (b - a) : 0;
return function(x) {
return (x - a) * b;
};
}
function d3_uninterpolateClamp(a, b) {
b = b - (a = +a) ? 1 / (b - a) : 0;
return function(x) {
return Math.max(0, Math.min(1, (x - a) * b));
};
}
d3.layout = {};
d3.layout.bundle = function() {
return function(links) {
var paths = [], i = -1, n = links.length;
while (++i < n) paths.push(d3_layout_bundlePath(links[i]));
return paths;
};
};
function d3_layout_bundlePath(link) {
var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ];
while (start !== lca) {
start = start.parent;
points.push(start);
}
var k = points.length;
while (end !== lca) {
points.splice(k, 0, end);
end = end.parent;
}
return points;
}
function d3_layout_bundleAncestors(node) {
var ancestors = [], parent = node.parent;
while (parent != null) {
ancestors.push(node);
node = parent;
parent = parent.parent;
}
ancestors.push(node);
return ancestors;
}
function d3_layout_bundleLeastCommonAncestor(a, b) {
if (a === b) return a;
var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null;
while (aNode === bNode) {
sharedNode = aNode;
aNode = aNodes.pop();
bNode = bNodes.pop();
}
return sharedNode;
}
d3.layout.chord = function() {
var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords;
function relayout() {
var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j;
chords = [];
groups = [];
k = 0, i = -1;
while (++i < n) {
x = 0, j = -1;
while (++j < n) {
x += matrix[i][j];
}
groupSums.push(x);
subgroupIndex.push(d3.range(n));
k += x;
}
if (sortGroups) {
groupIndex.sort(function(a, b) {
return sortGroups(groupSums[a], groupSums[b]);
});
}
if (sortSubgroups) {
subgroupIndex.forEach(function(d, i) {
d.sort(function(a, b) {
return sortSubgroups(matrix[i][a], matrix[i][b]);
});
});
}
k = (τ - padding * n) / k;
x = 0, i = -1;
while (++i < n) {
x0 = x, j = -1;
while (++j < n) {
var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k;
subgroups[di + "-" + dj] = {
index: di,
subindex: dj,
startAngle: a0,
endAngle: a1,
value: v
};
}
groups[di] = {
index: di,
startAngle: x0,
endAngle: x,
value: (x - x0) / k
};
x += padding;
}
i = -1;
while (++i < n) {
j = i - 1;
while (++j < n) {
var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i];
if (source.value || target.value) {
chords.push(source.value < target.value ? {
source: target,
target: source
} : {
source: source,
target: target
});
}
}
}
if (sortChords) resort();
}
function resort() {
chords.sort(function(a, b) {
return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2);
});
}
chord.matrix = function(x) {
if (!arguments.length) return matrix;
n = (matrix = x) && matrix.length;
chords = groups = null;
return chord;
};
chord.padding = function(x) {
if (!arguments.length) return padding;
padding = x;
chords = groups = null;
return chord;
};
chord.sortGroups = function(x) {
if (!arguments.length) return sortGroups;
sortGroups = x;
chords = groups = null;
return chord;
};
chord.sortSubgroups = function(x) {
if (!arguments.length) return sortSubgroups;
sortSubgroups = x;
chords = null;
return chord;
};
chord.sortChords = function(x) {
if (!arguments.length) return sortChords;
sortChords = x;
if (chords) resort();
return chord;
};
chord.chords = function() {
if (!chords) relayout();
return chords;
};
chord.groups = function() {
if (!groups) relayout();
return groups;
};
return chord;
};
d3.layout.force = function() {
var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges;
function repulse(node) {
return function(quad, x1, _, x2) {
if (quad.point !== node) {
var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy;
if (dw * dw / theta2 < dn) {
if (dn < chargeDistance2) {
var k = quad.charge / dn;
node.px -= dx * k;
node.py -= dy * k;
}
return true;
}
if (quad.point && dn && dn < chargeDistance2) {
var k = quad.pointCharge / dn;
node.px -= dx * k;
node.py -= dy * k;
}
}
return !quad.charge;
};
}
force.tick = function() {
if ((alpha *= .99) < .005) {
event.end({
type: "end",
alpha: alpha = 0
});
return true;
}
var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y;
for (i = 0; i < m; ++i) {
o = links[i];
s = o.source;
t = o.target;
x = t.x - s.x;
y = t.y - s.y;
if (l = x * x + y * y) {
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
x *= l;
y *= l;
t.x -= x * (k = s.weight / (t.weight + s.weight));
t.y -= y * k;
s.x += x * (k = 1 - k);
s.y += y * k;
}
}
if (k = alpha * gravity) {
x = size[0] / 2;
y = size[1] / 2;
i = -1;
if (k) while (++i < n) {
o = nodes[i];
o.x += (x - o.x) * k;
o.y += (y - o.y) * k;
}
}
if (charge) {
d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges);
i = -1;
while (++i < n) {
if (!(o = nodes[i]).fixed) {
q.visit(repulse(o));
}
}
}
i = -1;
while (++i < n) {
o = nodes[i];
if (o.fixed) {
o.x = o.px;
o.y = o.py;
} else {
o.x -= (o.px - (o.px = o.x)) * friction;
o.y -= (o.py - (o.py = o.y)) * friction;
}
}
event.tick({
type: "tick",
alpha: alpha
});
};
force.nodes = function(x) {
if (!arguments.length) return nodes;
nodes = x;
return force;
};
force.links = function(x) {
if (!arguments.length) return links;
links = x;
return force;
};
force.size = function(x) {
if (!arguments.length) return size;
size = x;
return force;
};
force.linkDistance = function(x) {
if (!arguments.length) return linkDistance;
linkDistance = typeof x === "function" ? x : +x;
return force;
};
force.distance = force.linkDistance;
force.linkStrength = function(x) {
if (!arguments.length) return linkStrength;
linkStrength = typeof x === "function" ? x : +x;
return force;
};
force.friction = function(x) {
if (!arguments.length) return friction;
friction = +x;
return force;
};
force.charge = function(x) {
if (!arguments.length) return charge;
charge = typeof x === "function" ? x : +x;
return force;
};
force.chargeDistance = function(x) {
if (!arguments.length) return Math.sqrt(chargeDistance2);
chargeDistance2 = x * x;
return force;
};
force.gravity = function(x) {
if (!arguments.length) return gravity;
gravity = +x;
return force;
};
force.theta = function(x) {
if (!arguments.length) return Math.sqrt(theta2);
theta2 = x * x;
return force;
};
force.alpha = function(x) {
if (!arguments.length) return alpha;
x = +x;
if (alpha) {
if (x > 0) alpha = x; else alpha = 0;
} else if (x > 0) {
event.start({
type: "start",
alpha: alpha = x
});
d3.timer(force.tick);
}
return force;
};
force.start = function() {
var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o;
for (i = 0; i < n; ++i) {
(o = nodes[i]).index = i;
o.weight = 0;
}
for (i = 0; i < m; ++i) {
o = links[i];
if (typeof o.source == "number") o.source = nodes[o.source];
if (typeof o.target == "number") o.target = nodes[o.target];
++o.source.weight;
++o.target.weight;
}
for (i = 0; i < n; ++i) {
o = nodes[i];
if (isNaN(o.x)) o.x = position("x", w);
if (isNaN(o.y)) o.y = position("y", h);
if (isNaN(o.px)) o.px = o.x;
if (isNaN(o.py)) o.py = o.y;
}
distances = [];
if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance;
strengths = [];
if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength;
charges = [];
if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge;
function position(dimension, size) {
if (!neighbors) {
neighbors = new Array(n);
for (j = 0; j < n; ++j) {
neighbors[j] = [];
}
for (j = 0; j < m; ++j) {
var o = links[j];
neighbors[o.source.index].push(o.target);
neighbors[o.target.index].push(o.source);
}
}
var candidates = neighbors[i], j = -1, m = candidates.length, x;
while (++j < m) if (!isNaN(x = candidates[j][dimension])) return x;
return Math.random() * size;
}
return force.resume();
};
force.resume = function() {
return force.alpha(.1);
};
force.stop = function() {
return force.alpha(0);
};
force.drag = function() {
if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend);
if (!arguments.length) return drag;
this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag);
};
function dragmove(d) {
d.px = d3.event.x, d.py = d3.event.y;
force.resume();
}
return d3.rebind(force, event, "on");
};
function d3_layout_forceDragstart(d) {
d.fixed |= 2;
}
function d3_layout_forceDragend(d) {
d.fixed &= ~6;
}
function d3_layout_forceMouseover(d) {
d.fixed |= 4;
d.px = d.x, d.py = d.y;
}
function d3_layout_forceMouseout(d) {
d.fixed &= ~4;
}
function d3_layout_forceAccumulate(quad, alpha, charges) {
var cx = 0, cy = 0;
quad.charge = 0;
if (!quad.leaf) {
var nodes = quad.nodes, n = nodes.length, i = -1, c;
while (++i < n) {
c = nodes[i];
if (c == null) continue;
d3_layout_forceAccumulate(c, alpha, charges);
quad.charge += c.charge;
cx += c.charge * c.cx;
cy += c.charge * c.cy;
}
}
if (quad.point) {
if (!quad.leaf) {
quad.point.x += Math.random() - .5;
quad.point.y += Math.random() - .5;
}
var k = alpha * charges[quad.point.index];
quad.charge += quad.pointCharge = k;
cx += k * quad.point.x;
cy += k * quad.point.y;
}
quad.cx = cx / quad.charge;
quad.cy = cy / quad.charge;
}
var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity;
d3.layout.hierarchy = function() {
var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue;
function hierarchy(root) {
var stack = [ root ], nodes = [], node;
root.depth = 0;
while ((node = stack.pop()) != null) {
nodes.push(node);
if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) {
var n, childs, child;
while (--n >= 0) {
stack.push(child = childs[n]);
child.parent = node;
child.depth = node.depth + 1;
}
if (value) node.value = 0;
node.children = childs;
} else {
if (value) node.value = +value.call(hierarchy, node, node.depth) || 0;
delete node.children;
}
}
d3_layout_hierarchyVisitAfter(root, function(node) {
var childs, parent;
if (sort && (childs = node.children)) childs.sort(sort);
if (value && (parent = node.parent)) parent.value += node.value;
});
return nodes;
}
hierarchy.sort = function(x) {
if (!arguments.length) return sort;
sort = x;
return hierarchy;
};
hierarchy.children = function(x) {
if (!arguments.length) return children;
children = x;
return hierarchy;
};
hierarchy.value = function(x) {
if (!arguments.length) return value;
value = x;
return hierarchy;
};
hierarchy.revalue = function(root) {
if (value) {
d3_layout_hierarchyVisitBefore(root, function(node) {
if (node.children) node.value = 0;
});
d3_layout_hierarchyVisitAfter(root, function(node) {
var parent;
if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0;
if (parent = node.parent) parent.value += node.value;
});
}
return root;
};
return hierarchy;
};
function d3_layout_hierarchyRebind(object, hierarchy) {
d3.rebind(object, hierarchy, "sort", "children", "value");
object.nodes = object;
object.links = d3_layout_hierarchyLinks;
return object;
}
function d3_layout_hierarchyVisitBefore(node, callback) {
var nodes = [ node ];
while ((node = nodes.pop()) != null) {
callback(node);
if ((children = node.children) && (n = children.length)) {
var n, children;
while (--n >= 0) nodes.push(children[n]);
}
}
}
function d3_layout_hierarchyVisitAfter(node, callback) {
var nodes = [ node ], nodes2 = [];
while ((node = nodes.pop()) != null) {
nodes2.push(node);
if ((children = node.children) && (n = children.length)) {
var i = -1, n, children;
while (++i < n) nodes.push(children[i]);
}
}
while ((node = nodes2.pop()) != null) {
callback(node);
}
}
function d3_layout_hierarchyChildren(d) {
return d.children;
}
function d3_layout_hierarchyValue(d) {
return d.value;
}
function d3_layout_hierarchySort(a, b) {
return b.value - a.value;
}
function d3_layout_hierarchyLinks(nodes) {
return d3.merge(nodes.map(function(parent) {
return (parent.children || []).map(function(child) {
return {
source: parent,
target: child
};
});
}));
}
d3.layout.partition = function() {
var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ];
function position(node, x, dx, dy) {
var children = node.children;
node.x = x;
node.y = node.depth * dy;
node.dx = dx;
node.dy = dy;
if (children && (n = children.length)) {
var i = -1, n, c, d;
dx = node.value ? dx / node.value : 0;
while (++i < n) {
position(c = children[i], x, d = c.value * dx, dy);
x += d;
}
}
}
function depth(node) {
var children = node.children, d = 0;
if (children && (n = children.length)) {
var i = -1, n;
while (++i < n) d = Math.max(d, depth(children[i]));
}
return 1 + d;
}
function partition(d, i) {
var nodes = hierarchy.call(this, d, i);
position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));
return nodes;
}
partition.size = function(x) {
if (!arguments.length) return size;
size = x;
return partition;
};
return d3_layout_hierarchyRebind(partition, hierarchy);
};
d3.layout.pie = function() {
var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ;
function pie(data) {
var values = data.map(function(d, i) {
return +value.call(pie, d, i);
});
var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle);
var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values);
var index = d3.range(data.length);
if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) {
return values[j] - values[i];
} : function(i, j) {
return sort(data[i], data[j]);
});
var arcs = [];
index.forEach(function(i) {
var d;
arcs[i] = {
data: data[i],
value: d = values[i],
startAngle: a,
endAngle: a += d * k
};
});
return arcs;
}
pie.value = function(x) {
if (!arguments.length) return value;
value = x;
return pie;
};
pie.sort = function(x) {
if (!arguments.length) return sort;
sort = x;
return pie;
};
pie.startAngle = function(x) {
if (!arguments.length) return startAngle;
startAngle = x;
return pie;
};
pie.endAngle = function(x) {
if (!arguments.length) return endAngle;
endAngle = x;
return pie;
};
return pie;
};
var d3_layout_pieSortByValue = {};
d3.layout.stack = function() {
var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY;
function stack(data, index) {
var series = data.map(function(d, i) {
return values.call(stack, d, i);
});
var points = series.map(function(d) {
return d.map(function(v, i) {
return [ x.call(stack, v, i), y.call(stack, v, i) ];
});
});
var orders = order.call(stack, points, index);
series = d3.permute(series, orders);
points = d3.permute(points, orders);
var offsets = offset.call(stack, points, index);
var n = series.length, m = series[0].length, i, j, o;
for (j = 0; j < m; ++j) {
out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
for (i = 1; i < n; ++i) {
out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
}
}
return data;
}
stack.values = function(x) {
if (!arguments.length) return values;
values = x;
return stack;
};
stack.order = function(x) {
if (!arguments.length) return order;
order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault;
return stack;
};
stack.offset = function(x) {
if (!arguments.length) return offset;
offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero;
return stack;
};
stack.x = function(z) {
if (!arguments.length) return x;
x = z;
return stack;
};
stack.y = function(z) {
if (!arguments.length) return y;
y = z;
return stack;
};
stack.out = function(z) {
if (!arguments.length) return out;
out = z;
return stack;
};
return stack;
};
function d3_layout_stackX(d) {
return d.x;
}
function d3_layout_stackY(d) {
return d.y;
}
function d3_layout_stackOut(d, y0, y) {
d.y0 = y0;
d.y = y;
}
var d3_layout_stackOrders = d3.map({
"inside-out": function(data) {
var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) {
return max[a] - max[b];
}), top = 0, bottom = 0, tops = [], bottoms = [];
for (i = 0; i < n; ++i) {
j = index[i];
if (top < bottom) {
top += sums[j];
tops.push(j);
} else {
bottom += sums[j];
bottoms.push(j);
}
}
return bottoms.reverse().concat(tops);
},
reverse: function(data) {
return d3.range(data.length).reverse();
},
"default": d3_layout_stackOrderDefault
});
var d3_layout_stackOffsets = d3.map({
silhouette: function(data) {
var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = [];
for (j = 0; j < m; ++j) {
for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
if (o > max) max = o;
sums.push(o);
}
for (j = 0; j < m; ++j) {
y0[j] = (max - sums[j]) / 2;
}
return y0;
},
wiggle: function(data) {
var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = [];
y0[0] = o = o0 = 0;
for (j = 1; j < m; ++j) {
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
}
s2 += s3 * data[i][j][1];
}
y0[j] = o -= s1 ? s2 / s1 * dx : 0;
if (o < o0) o0 = o;
}
for (j = 0; j < m; ++j) y0[j] -= o0;
return y0;
},
expand: function(data) {
var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = [];
for (j = 0; j < m; ++j) {
for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k;
}
for (j = 0; j < m; ++j) y0[j] = 0;
return y0;
},
zero: d3_layout_stackOffsetZero
});
function d3_layout_stackOrderDefault(data) {
return d3.range(data.length);
}
function d3_layout_stackOffsetZero(data) {
var j = -1, m = data[0].length, y0 = [];
while (++j < m) y0[j] = 0;
return y0;
}
function d3_layout_stackMaxIndex(array) {
var i = 1, j = 0, v = array[0][1], k, n = array.length;
for (;i < n; ++i) {
if ((k = array[i][1]) > v) {
j = i;
v = k;
}
}
return j;
}
function d3_layout_stackReduceSum(d) {
return d.reduce(d3_layout_stackSum, 0);
}
function d3_layout_stackSum(p, d) {
return p + d[1];
}
d3.layout.histogram = function() {
var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges;
function histogram(data, i) {
var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x;
while (++i < m) {
bin = bins[i] = [];
bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
bin.y = 0;
}
if (m > 0) {
i = -1;
while (++i < n) {
x = values[i];
if (x >= range[0] && x <= range[1]) {
bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
bin.y += k;
bin.push(data[i]);
}
}
}
return bins;
}
histogram.value = function(x) {
if (!arguments.length) return valuer;
valuer = x;
return histogram;
};
histogram.range = function(x) {
if (!arguments.length) return ranger;
ranger = d3_functor(x);
return histogram;
};
histogram.bins = function(x) {
if (!arguments.length) return binner;
binner = typeof x === "number" ? function(range) {
return d3_layout_histogramBinFixed(range, x);
} : d3_functor(x);
return histogram;
};
histogram.frequency = function(x) {
if (!arguments.length) return frequency;
frequency = !!x;
return histogram;
};
return histogram;
};
function d3_layout_histogramBinSturges(range, values) {
return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
}
function d3_layout_histogramBinFixed(range, n) {
var x = -1, b = +range[0], m = (range[1] - b) / n, f = [];
while (++x <= n) f[x] = m * x + b;
return f;
}
function d3_layout_histogramRange(values) {
return [ d3.min(values), d3.max(values) ];
}
d3.layout.pack = function() {
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius;
function pack(d, i) {
var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() {
return radius;
};
root.x = root.y = 0;
d3_layout_hierarchyVisitAfter(root, function(d) {
d.r = +r(d.value);
});
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
if (padding) {
var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2;
d3_layout_hierarchyVisitAfter(root, function(d) {
d.r += dr;
});
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
d3_layout_hierarchyVisitAfter(root, function(d) {
d.r -= dr;
});
}
d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h));
return nodes;
}
pack.size = function(_) {
if (!arguments.length) return size;
size = _;
return pack;
};
pack.radius = function(_) {
if (!arguments.length) return radius;
radius = _ == null || typeof _ === "function" ? _ : +_;
return pack;
};
pack.padding = function(_) {
if (!arguments.length) return padding;
padding = +_;
return pack;
};
return d3_layout_hierarchyRebind(pack, hierarchy);
};
function d3_layout_packSort(a, b) {
return a.value - b.value;
}
function d3_layout_packInsert(a, b) {
var c = a._pack_next;
a._pack_next = b;
b._pack_prev = a;
b._pack_next = c;
c._pack_prev = b;
}
function d3_layout_packSplice(a, b) {
a._pack_next = b;
b._pack_prev = a;
}
function d3_layout_packIntersects(a, b) {
var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;
return .999 * dr * dr > dx * dx + dy * dy;
}
function d3_layout_packSiblings(node) {
if (!(nodes = node.children) || !(n = nodes.length)) return;
var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;
function bound(node) {
xMin = Math.min(node.x - node.r, xMin);
xMax = Math.max(node.x + node.r, xMax);
yMin = Math.min(node.y - node.r, yMin);
yMax = Math.max(node.y + node.r, yMax);
}
nodes.forEach(d3_layout_packLink);
a = nodes[0];
a.x = -a.r;
a.y = 0;
bound(a);
if (n > 1) {
b = nodes[1];
b.x = b.r;
b.y = 0;
bound(b);
if (n > 2) {
c = nodes[2];
d3_layout_packPlace(a, b, c);
bound(c);
d3_layout_packInsert(a, c);
a._pack_prev = c;
d3_layout_packInsert(c, b);
b = a._pack_next;
for (i = 3; i < n; i++) {
d3_layout_packPlace(a, b, c = nodes[i]);
var isect = 0, s1 = 1, s2 = 1;
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
if (d3_layout_packIntersects(j, c)) {
isect = 1;
break;
}
}
if (isect == 1) {
for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
if (d3_layout_packIntersects(k, c)) {
break;
}
}
}
if (isect) {
if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b);
i--;
} else {
d3_layout_packInsert(a, c);
b = c;
bound(c);
}
}
}
}
var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;
for (i = 0; i < n; i++) {
c = nodes[i];
c.x -= cx;
c.y -= cy;
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
}
node.r = cr;
nodes.forEach(d3_layout_packUnlink);
}
function d3_layout_packLink(node) {
node._pack_next = node._pack_prev = node;
}
function d3_layout_packUnlink(node) {
delete node._pack_next;
delete node._pack_prev;
}
function d3_layout_packTransform(node, x, y, k) {
var children = node.children;
node.x = x += k * node.x;
node.y = y += k * node.y;
node.r *= k;
if (children) {
var i = -1, n = children.length;
while (++i < n) d3_layout_packTransform(children[i], x, y, k);
}
}
function d3_layout_packPlace(a, b, c) {
var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y;
if (db && (dx || dy)) {
var da = b.r + c.r, dc = dx * dx + dy * dy;
da *= da;
db *= db;
var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
c.x = a.x + x * dx + y * dy;
c.y = a.y + x * dy - y * dx;
} else {
c.x = a.x + db;
c.y = a.y;
}
}
d3.layout.tree = function() {
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null;
function tree(d, i) {
var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0);
d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z;
d3_layout_hierarchyVisitBefore(root1, secondWalk);
if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else {
var left = root0, right = root0, bottom = root0;
d3_layout_hierarchyVisitBefore(root0, function(node) {
if (node.x < left.x) left = node;
if (node.x > right.x) right = node;
if (node.depth > bottom.depth) bottom = node;
});
var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1);
d3_layout_hierarchyVisitBefore(root0, function(node) {
node.x = (node.x + tx) * kx;
node.y = node.depth * ky;
});
}
return nodes;
}
function wrapTree(root0) {
var root1 = {
A: null,
children: [ root0 ]
}, queue = [ root1 ], node1;
while ((node1 = queue.pop()) != null) {
for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) {
queue.push((children[i] = child = {
_: children[i],
parent: node1,
children: (child = children[i].children) && child.slice() || [],
A: null,
a: null,
z: 0,
m: 0,
c: 0,
s: 0,
t: null,
i: i
}).a = child);
}
}
return root1.children[0];
}
function firstWalk(v) {
var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null;
if (children.length) {
d3_layout_treeShift(v);
var midpoint = (children[0].z + children[children.length - 1].z) / 2;
if (w) {
v.z = w.z + separation(v._, w._);
v.m = v.z - midpoint;
} else {
v.z = midpoint;
}
} else if (w) {
v.z = w.z + separation(v._, w._);
}
v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
}
function secondWalk(v) {
v._.x = v.z + v.parent.m;
v.m += v.parent.m;
}
function apportion(v, w, ancestor) {
if (w) {
var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift;
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
vom = d3_layout_treeLeft(vom);
vop = d3_layout_treeRight(vop);
vop.a = v;
shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
if (shift > 0) {
d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift);
sip += shift;
sop += shift;
}
sim += vim.m;
sip += vip.m;
som += vom.m;
sop += vop.m;
}
if (vim && !d3_layout_treeRight(vop)) {
vop.t = vim;
vop.m += sim - sop;
}
if (vip && !d3_layout_treeLeft(vom)) {
vom.t = vip;
vom.m += sip - som;
ancestor = v;
}
}
return ancestor;
}
function sizeNode(node) {
node.x *= size[0];
node.y = node.depth * size[1];
}
tree.separation = function(x) {
if (!arguments.length) return separation;
separation = x;
return tree;
};
tree.size = function(x) {
if (!arguments.length) return nodeSize ? null : size;
nodeSize = (size = x) == null ? sizeNode : null;
return tree;
};
tree.nodeSize = function(x) {
if (!arguments.length) return nodeSize ? size : null;
nodeSize = (size = x) == null ? null : sizeNode;
return tree;
};
return d3_layout_hierarchyRebind(tree, hierarchy);
};
function d3_layout_treeSeparation(a, b) {
return a.parent == b.parent ? 1 : 2;
}
function d3_layout_treeLeft(v) {
var children = v.children;
return children.length ? children[0] : v.t;
}
function d3_layout_treeRight(v) {
var children = v.children, n;
return (n = children.length) ? children[n - 1] : v.t;
}
function d3_layout_treeMove(wm, wp, shift) {
var change = shift / (wp.i - wm.i);
wp.c -= change;
wp.s += shift;
wm.c += change;
wp.z += shift;
wp.m += shift;
}
function d3_layout_treeShift(v) {
var shift = 0, change = 0, children = v.children, i = children.length, w;
while (--i >= 0) {
w = children[i];
w.z += shift;
w.m += shift;
shift += w.s + (change += w.c);
}
}
function d3_layout_treeAncestor(vim, v, ancestor) {
return vim.a.parent === v.parent ? vim.a : ancestor;
}
d3.layout.cluster = function() {
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false;
function cluster(d, i) {
var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0;
d3_layout_hierarchyVisitAfter(root, function(node) {
var children = node.children;
if (children && children.length) {
node.x = d3_layout_clusterX(children);
node.y = d3_layout_clusterY(children);
} else {
node.x = previousNode ? x += separation(node, previousNode) : 0;
node.y = 0;
previousNode = node;
}
});
var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2;
d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) {
node.x = (node.x - root.x) * size[0];
node.y = (root.y - node.y) * size[1];
} : function(node) {
node.x = (node.x - x0) / (x1 - x0) * size[0];
node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];
});
return nodes;
}
cluster.separation = function(x) {
if (!arguments.length) return separation;
separation = x;
return cluster;
};
cluster.size = function(x) {
if (!arguments.length) return nodeSize ? null : size;
nodeSize = (size = x) == null;
return cluster;
};
cluster.nodeSize = function(x) {
if (!arguments.length) return nodeSize ? size : null;
nodeSize = (size = x) != null;
return cluster;
};
return d3_layout_hierarchyRebind(cluster, hierarchy);
};
function d3_layout_clusterY(children) {
return 1 + d3.max(children, function(child) {
return child.y;
});
}
function d3_layout_clusterX(children) {
return children.reduce(function(x, child) {
return x + child.x;
}, 0) / children.length;
}
function d3_layout_clusterLeft(node) {
var children = node.children;
return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
}
function d3_layout_clusterRight(node) {
var children = node.children, n;
return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
}
d3.layout.treemap = function() {
var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5));
function scale(children, k) {
var i = -1, n = children.length, child, area;
while (++i < n) {
area = (child = children[i]).value * (k < 0 ? 0 : k);
child.area = isNaN(area) || area <= 0 ? 0 : area;
}
}
function squarify(node) {
var children = node.children;
if (children && children.length) {
var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n;
scale(remaining, rect.dx * rect.dy / node.value);
row.area = 0;
while ((n = remaining.length) > 0) {
row.push(child = remaining[n - 1]);
row.area += child.area;
if (mode !== "squarify" || (score = worst(row, u)) <= best) {
remaining.pop();
best = score;
} else {
row.area -= row.pop().area;
position(row, u, rect, false);
u = Math.min(rect.dx, rect.dy);
row.length = row.area = 0;
best = Infinity;
}
}
if (row.length) {
position(row, u, rect, true);
row.length = row.area = 0;
}
children.forEach(squarify);
}
}
function stickify(node) {
var children = node.children;
if (children && children.length) {
var rect = pad(node), remaining = children.slice(), child, row = [];
scale(remaining, rect.dx * rect.dy / node.value);
row.area = 0;
while (child = remaining.pop()) {
row.push(child);
row.area += child.area;
if (child.z != null) {
position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
row.length = row.area = 0;
}
}
children.forEach(stickify);
}
}
function worst(row, u) {
var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length;
while (++i < n) {
if (!(r = row[i].area)) continue;
if (r < rmin) rmin = r;
if (r > rmax) rmax = r;
}
s *= s;
u *= u;
return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity;
}
function position(row, u, rect, flush) {
var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o;
if (u == rect.dx) {
if (flush || v > rect.dy) v = rect.dy;
while (++i < n) {
o = row[i];
o.x = x;
o.y = y;
o.dy = v;
x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);
}
o.z = true;
o.dx += rect.x + rect.dx - x;
rect.y += v;
rect.dy -= v;
} else {
if (flush || v > rect.dx) v = rect.dx;
while (++i < n) {
o = row[i];
o.x = x;
o.y = y;
o.dx = v;
y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);
}
o.z = false;
o.dy += rect.y + rect.dy - y;
rect.x += v;
rect.dx -= v;
}
}
function treemap(d) {
var nodes = stickies || hierarchy(d), root = nodes[0];
root.x = 0;
root.y = 0;
root.dx = size[0];
root.dy = size[1];
if (stickies) hierarchy.revalue(root);
scale([ root ], root.dx * root.dy / root.value);
(stickies ? stickify : squarify)(root);
if (sticky) stickies = nodes;
return nodes;
}
treemap.size = function(x) {
if (!arguments.length) return size;
size = x;
return treemap;
};
treemap.padding = function(x) {
if (!arguments.length) return padding;
function padFunction(node) {
var p = x.call(treemap, node, node.depth);
return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p);
}
function padConstant(node) {
return d3_layout_treemapPad(node, x);
}
var type;
pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ],
padConstant) : padConstant;
return treemap;
};
treemap.round = function(x) {
if (!arguments.length) return round != Number;
round = x ? Math.round : Number;
return treemap;
};
treemap.sticky = function(x) {
if (!arguments.length) return sticky;
sticky = x;
stickies = null;
return treemap;
};
treemap.ratio = function(x) {
if (!arguments.length) return ratio;
ratio = x;
return treemap;
};
treemap.mode = function(x) {
if (!arguments.length) return mode;
mode = x + "";
return treemap;
};
return d3_layout_hierarchyRebind(treemap, hierarchy);
};
function d3_layout_treemapPadNull(node) {
return {
x: node.x,
y: node.y,
dx: node.dx,
dy: node.dy
};
}
function d3_layout_treemapPad(node, padding) {
var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2];
if (dx < 0) {
x += dx / 2;
dx = 0;
}
if (dy < 0) {
y += dy / 2;
dy = 0;
}
return {
x: x,
y: y,
dx: dx,
dy: dy
};
}
d3.random = {
normal: function(µ, σ) {
var n = arguments.length;
if (n < 2) σ = 1;
if (n < 1) µ = 0;
return function() {
var x, y, r;
do {
x = Math.random() * 2 - 1;
y = Math.random() * 2 - 1;
r = x * x + y * y;
} while (!r || r > 1);
return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r);
};
},
logNormal: function() {
var random = d3.random.normal.apply(d3, arguments);
return function() {
return Math.exp(random());
};
},
bates: function(m) {
var random = d3.random.irwinHall(m);
return function() {
return random() / m;
};
},
irwinHall: function(m) {
return function() {
for (var s = 0, j = 0; j < m; j++) s += Math.random();
return s;
};
}
};
d3.scale = {};
function d3_scaleExtent(domain) {
var start = domain[0], stop = domain[domain.length - 1];
return start < stop ? [ start, stop ] : [ stop, start ];
}
function d3_scaleRange(scale) {
return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
}
function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);
return function(x) {
return i(u(x));
};
}
function d3_scale_nice(domain, nice) {
var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
if (x1 < x0) {
dx = i0, i0 = i1, i1 = dx;
dx = x0, x0 = x1, x1 = dx;
}
domain[i0] = nice.floor(x0);
domain[i1] = nice.ceil(x1);
return domain;
}
function d3_scale_niceStep(step) {
return step ? {
floor: function(x) {
return Math.floor(x / step) * step;
},
ceil: function(x) {
return Math.ceil(x / step) * step;
}
} : d3_scale_niceIdentity;
}
var d3_scale_niceIdentity = {
floor: d3_identity,
ceil: d3_identity
};
function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;
if (domain[k] < domain[0]) {
domain = domain.slice().reverse();
range = range.slice().reverse();
}
while (++j <= k) {
u.push(uninterpolate(domain[j - 1], domain[j]));
i.push(interpolate(range[j - 1], range[j]));
}
return function(x) {
var j = d3.bisect(domain, x, 1, k) - 1;
return i[j](u[j](x));
};
}
d3.scale.linear = function() {
return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false);
};
function d3_scale_linear(domain, range, interpolate, clamp) {
var output, input;
function rescale() {
var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
output = linear(domain, range, uninterpolate, interpolate);
input = linear(range, domain, uninterpolate, d3_interpolate);
return scale;
}
function scale(x) {
return output(x);
}
scale.invert = function(y) {
return input(y);
};
scale.domain = function(x) {
if (!arguments.length) return domain;
domain = x.map(Number);
return rescale();
};
scale.range = function(x) {
if (!arguments.length) return range;
range = x;
return rescale();
};
scale.rangeRound = function(x) {
return scale.range(x).interpolate(d3_interpolateRound);
};
scale.clamp = function(x) {
if (!arguments.length) return clamp;
clamp = x;
return rescale();
};
scale.interpolate = function(x) {
if (!arguments.length) return interpolate;
interpolate = x;
return rescale();
};
scale.ticks = function(m) {
return d3_scale_linearTicks(domain, m);
};
scale.tickFormat = function(m, format) {
return d3_scale_linearTickFormat(domain, m, format);
};
scale.nice = function(m) {
d3_scale_linearNice(domain, m);
return rescale();
};
scale.copy = function() {
return d3_scale_linear(domain, range, interpolate, clamp);
};
return rescale();
}
function d3_scale_linearRebind(scale, linear) {
return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
}
function d3_scale_linearNice(domain, m) {
return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
}
function d3_scale_linearTickRange(domain, m) {
if (m == null) m = 10;
var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;
if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;
extent[0] = Math.ceil(extent[0] / step) * step;
extent[1] = Math.floor(extent[1] / step) * step + step * .5;
extent[2] = step;
return extent;
}
function d3_scale_linearTicks(domain, m) {
return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
}
function d3_scale_linearTickFormat(domain, m, format) {
var range = d3_scale_linearTickRange(domain, m);
if (format) {
var match = d3_format_re.exec(format);
match.shift();
if (match[8] === "s") {
var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1])));
if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2]));
match[8] = "f";
format = d3.format(match.join(""));
return function(d) {
return format(prefix.scale(d)) + prefix.symbol;
};
}
if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range);
format = match.join("");
} else {
format = ",." + d3_scale_linearPrecision(range[2]) + "f";
}
return d3.format(format);
}
var d3_scale_linearFormatSignificant = {
s: 1,
g: 1,
p: 1,
r: 1,
e: 1
};
function d3_scale_linearPrecision(value) {
return -Math.floor(Math.log(value) / Math.LN10 + .01);
}
function d3_scale_linearFormatPrecision(type, range) {
var p = d3_scale_linearPrecision(range[2]);
return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2;
}
d3.scale.log = function() {
return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]);
};
function d3_scale_log(linear, base, positive, domain) {
function log(x) {
return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base);
}
function pow(x) {
return positive ? Math.pow(base, x) : -Math.pow(base, -x);
}
function scale(x) {
return linear(log(x));
}
scale.invert = function(x) {
return pow(linear.invert(x));
};
scale.domain = function(x) {
if (!arguments.length) return domain;
positive = x[0] >= 0;
linear.domain((domain = x.map(Number)).map(log));
return scale;
};
scale.base = function(_) {
if (!arguments.length) return base;
base = +_;
linear.domain(domain.map(log));
return scale;
};
scale.nice = function() {
var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative);
linear.domain(niced);
domain = niced.map(pow);
return scale;
};
scale.ticks = function() {
var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base;
if (isFinite(j - i)) {
if (positive) {
for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k);
ticks.push(pow(i));
} else {
ticks.push(pow(i));
for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k);
}
for (i = 0; ticks[i] < u; i++) {}
for (j = ticks.length; ticks[j - 1] > v; j--) {}
ticks = ticks.slice(i, j);
}
return ticks;
};
scale.tickFormat = function(n, format) {
if (!arguments.length) return d3_scale_logFormat;
if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format);
var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12,
Math.floor), e;
return function(d) {
return d / pow(f(log(d) + e)) <= k ? format(d) : "";
};
};
scale.copy = function() {
return d3_scale_log(linear.copy(), base, positive, domain);
};
return d3_scale_linearRebind(scale, linear);
}
var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = {
floor: function(x) {
return -Math.ceil(-x);
},
ceil: function(x) {
return -Math.floor(-x);
}
};
d3.scale.pow = function() {
return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]);
};
function d3_scale_pow(linear, exponent, domain) {
var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);
function scale(x) {
return linear(powp(x));
}
scale.invert = function(x) {
return powb(linear.invert(x));
};
scale.domain = function(x) {
if (!arguments.length) return domain;
linear.domain((domain = x.map(Number)).map(powp));
return scale;
};
scale.ticks = function(m) {
return d3_scale_linearTicks(domain, m);
};
scale.tickFormat = function(m, format) {
return d3_scale_linearTickFormat(domain, m, format);
};
scale.nice = function(m) {
return scale.domain(d3_scale_linearNice(domain, m));
};
scale.exponent = function(x) {
if (!arguments.length) return exponent;
powp = d3_scale_powPow(exponent = x);
powb = d3_scale_powPow(1 / exponent);
linear.domain(domain.map(powp));
return scale;
};
scale.copy = function() {
return d3_scale_pow(linear.copy(), exponent, domain);
};
return d3_scale_linearRebind(scale, linear);
}
function d3_scale_powPow(e) {
return function(x) {
return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
};
}
d3.scale.sqrt = function() {
return d3.scale.pow().exponent(.5);
};
d3.scale.ordinal = function() {
return d3_scale_ordinal([], {
t: "range",
a: [ [] ]
});
};
function d3_scale_ordinal(domain, ranger) {
var index, range, rangeBand;
function scale(x) {
return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length];
}
function steps(start, step) {
return d3.range(domain.length).map(function(i) {
return start + step * i;
});
}
scale.domain = function(x) {
if (!arguments.length) return domain;
domain = [];
index = new d3_Map();
var i = -1, n = x.length, xi;
while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
return scale[ranger.t].apply(scale, ranger.a);
};
scale.range = function(x) {
if (!arguments.length) return range;
range = x;
rangeBand = 0;
ranger = {
t: "range",
a: arguments
};
return scale;
};
scale.rangePoints = function(x, padding) {
if (arguments.length < 2) padding = 0;
var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding);
range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
rangeBand = 0;
ranger = {
t: "rangePoints",
a: arguments
};
return scale;
};
scale.rangeBands = function(x, padding, outerPadding) {
if (arguments.length < 2) padding = 0;
if (arguments.length < 3) outerPadding = padding;
var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);
range = steps(start + step * outerPadding, step);
if (reverse) range.reverse();
rangeBand = step * (1 - padding);
ranger = {
t: "rangeBands",
a: arguments
};
return scale;
};
scale.rangeRoundBands = function(x, padding, outerPadding) {
if (arguments.length < 2) padding = 0;
if (arguments.length < 3) outerPadding = padding;
var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step;
range = steps(start + Math.round(error / 2), step);
if (reverse) range.reverse();
rangeBand = Math.round(step * (1 - padding));
ranger = {
t: "rangeRoundBands",
a: arguments
};
return scale;
};
scale.rangeBand = function() {
return rangeBand;
};
scale.rangeExtent = function() {
return d3_scaleExtent(ranger.a[0]);
};
scale.copy = function() {
return d3_scale_ordinal(domain, ranger);
};
return scale.domain(domain);
}
d3.scale.category10 = function() {
return d3.scale.ordinal().range(d3_category10);
};
d3.scale.category20 = function() {
return d3.scale.ordinal().range(d3_category20);
};
d3.scale.category20b = function() {
return d3.scale.ordinal().range(d3_category20b);
};
d3.scale.category20c = function() {
return d3.scale.ordinal().range(d3_category20c);
};
var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString);
var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString);
var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString);
var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString);
d3.scale.quantile = function() {
return d3_scale_quantile([], []);
};
function d3_scale_quantile(domain, range) {
var thresholds;
function rescale() {
var k = 0, q = range.length;
thresholds = [];
while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
return scale;
}
function scale(x) {
if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)];
}
scale.domain = function(x) {
if (!arguments.length) return domain;
domain = x.filter(d3_number).sort(d3_ascending);
return rescale();
};
scale.range = function(x) {
if (!arguments.length) return range;
range = x;
return rescale();
};
scale.quantiles = function() {
return thresholds;
};
scale.invertExtent = function(y) {
y = range.indexOf(y);
return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ];
};
scale.copy = function() {
return d3_scale_quantile(domain, range);
};
return rescale();
}
d3.scale.quantize = function() {
return d3_scale_quantize(0, 1, [ 0, 1 ]);
};
function d3_scale_quantize(x0, x1, range) {
var kx, i;
function scale(x) {
return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
}
function rescale() {
kx = range.length / (x1 - x0);
i = range.length - 1;
return scale;
}
scale.domain = function(x) {
if (!arguments.length) return [ x0, x1 ];
x0 = +x[0];
x1 = +x[x.length - 1];
return rescale();
};
scale.range = function(x) {
if (!arguments.length) return range;
range = x;
return rescale();
};
scale.invertExtent = function(y) {
y = range.indexOf(y);
y = y < 0 ? NaN : y / kx + x0;
return [ y, y + 1 / kx ];
};
scale.copy = function() {
return d3_scale_quantize(x0, x1, range);
};
return rescale();
}
d3.scale.threshold = function() {
return d3_scale_threshold([ .5 ], [ 0, 1 ]);
};
function d3_scale_threshold(domain, range) {
function scale(x) {
if (x <= x) return range[d3.bisect(domain, x)];
}
scale.domain = function(_) {
if (!arguments.length) return domain;
domain = _;
return scale;
};
scale.range = function(_) {
if (!arguments.length) return range;
range = _;
return scale;
};
scale.invertExtent = function(y) {
y = range.indexOf(y);
return [ domain[y - 1], domain[y] ];
};
scale.copy = function() {
return d3_scale_threshold(domain, range);
};
return scale;
}
d3.scale.identity = function() {
return d3_scale_identity([ 0, 1 ]);
};
function d3_scale_identity(domain) {
function identity(x) {
return +x;
}
identity.invert = identity;
identity.domain = identity.range = function(x) {
if (!arguments.length) return domain;
domain = x.map(identity);
return identity;
};
identity.ticks = function(m) {
return d3_scale_linearTicks(domain, m);
};
identity.tickFormat = function(m, format) {
return d3_scale_linearTickFormat(domain, m, format);
};
identity.copy = function() {
return d3_scale_identity(domain);
};
return identity;
}
d3.svg = {};
d3.svg.arc = function() {
var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle;
function arc() {
var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0,
a0 = a1, a1 = da), a1 - a0), df = da < π ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1);
return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z";
}
arc.innerRadius = function(v) {
if (!arguments.length) return innerRadius;
innerRadius = d3_functor(v);
return arc;
};
arc.outerRadius = function(v) {
if (!arguments.length) return outerRadius;
outerRadius = d3_functor(v);
return arc;
};
arc.startAngle = function(v) {
if (!arguments.length) return startAngle;
startAngle = d3_functor(v);
return arc;
};
arc.endAngle = function(v) {
if (!arguments.length) return endAngle;
endAngle = d3_functor(v);
return arc;
};
arc.centroid = function() {
var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset;
return [ Math.cos(a) * r, Math.sin(a) * r ];
};
return arc;
};
var d3_svg_arcOffset = -halfπ, d3_svg_arcMax = τ - ε;
function d3_svg_arcInnerRadius(d) {
return d.innerRadius;
}
function d3_svg_arcOuterRadius(d) {
return d.outerRadius;
}
function d3_svg_arcStartAngle(d) {
return d.startAngle;
}
function d3_svg_arcEndAngle(d) {
return d.endAngle;
}
function d3_svg_line(projection) {
var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;
function line(data) {
var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
function segment() {
segments.push("M", interpolate(projection(points), tension));
}
while (++i < n) {
if (defined.call(this, d = data[i], i)) {
points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);
} else if (points.length) {
segment();
points = [];
}
}
if (points.length) segment();
return segments.length ? segments.join("") : null;
}
line.x = function(_) {
if (!arguments.length) return x;
x = _;
return line;
};
line.y = function(_) {
if (!arguments.length) return y;
y = _;
return line;
};
line.defined = function(_) {
if (!arguments.length) return defined;
defined = _;
return line;
};
line.interpolate = function(_) {
if (!arguments.length) return interpolateKey;
if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
return line;
};
line.tension = function(_) {
if (!arguments.length) return tension;
tension = _;
return line;
};
return line;
}
d3.svg.line = function() {
return d3_svg_line(d3_identity);
};
var d3_svg_lineInterpolators = d3.map({
linear: d3_svg_lineLinear,
"linear-closed": d3_svg_lineLinearClosed,
step: d3_svg_lineStep,
"step-before": d3_svg_lineStepBefore,
"step-after": d3_svg_lineStepAfter,
basis: d3_svg_lineBasis,
"basis-open": d3_svg_lineBasisOpen,
"basis-closed": d3_svg_lineBasisClosed,
bundle: d3_svg_lineBundle,
cardinal: d3_svg_lineCardinal,
"cardinal-open": d3_svg_lineCardinalOpen,
"cardinal-closed": d3_svg_lineCardinalClosed,
monotone: d3_svg_lineMonotone
});
d3_svg_lineInterpolators.forEach(function(key, value) {
value.key = key;
value.closed = /-closed$/.test(key);
});
function d3_svg_lineLinear(points) {
return points.join("L");
}
function d3_svg_lineLinearClosed(points) {
return d3_svg_lineLinear(points) + "Z";
}
function d3_svg_lineStep(points) {
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]);
if (n > 1) path.push("H", p[0]);
return path.join("");
}
function d3_svg_lineStepBefore(points) {
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
return path.join("");
}
function d3_svg_lineStepAfter(points) {
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
return path.join("");
}
function d3_svg_lineCardinalOpen(points, tension) {
return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension));
}
function d3_svg_lineCardinalClosed(points, tension) {
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]),
points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
}
function d3_svg_lineCardinal(points, tension) {
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));
}
function d3_svg_lineHermite(points, tangents) {
if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {
return d3_svg_lineLinear(points);
}
var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;
if (quad) {
path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1];
p0 = points[1];
pi = 2;
}
if (tangents.length > 1) {
t = tangents[1];
p = points[pi];
pi++;
path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
for (var i = 2; i < tangents.length; i++, pi++) {
p = points[pi];
t = tangents[i];
path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
}
}
if (quad) {
var lp = points[pi];
path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1];
}
return path;
}
function d3_svg_lineCardinalTangents(points, tension) {
var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;
while (++i < n) {
p0 = p1;
p1 = p2;
p2 = points[i];
tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);
}
return tangents;
}
function d3_svg_lineBasis(points) {
if (points.length < 3) return d3_svg_lineLinear(points);
var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
points.push(points[n - 1]);
while (++i <= n) {
pi = points[i];
px.shift();
px.push(pi[0]);
py.shift();
py.push(pi[1]);
d3_svg_lineBasisBezier(path, px, py);
}
points.pop();
path.push("L", pi);
return path.join("");
}
function d3_svg_lineBasisOpen(points) {
if (points.length < 4) return d3_svg_lineLinear(points);
var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ];
while (++i < 3) {
pi = points[i];
px.push(pi[0]);
py.push(pi[1]);
}
path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
--i;
while (++i < n) {
pi = points[i];
px.shift();
px.push(pi[0]);
py.shift();
py.push(pi[1]);
d3_svg_lineBasisBezier(path, px, py);
}
return path.join("");
}
function d3_svg_lineBasisClosed(points) {
var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = [];
while (++i < 4) {
pi = points[i % n];
px.push(pi[0]);
py.push(pi[1]);
}
path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
--i;
while (++i < m) {
pi = points[i % n];
px.shift();
px.push(pi[0]);
py.shift();
py.push(pi[1]);
d3_svg_lineBasisBezier(path, px, py);
}
return path.join("");
}
function d3_svg_lineBundle(points, tension) {
var n = points.length - 1;
if (n) {
var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t;
while (++i <= n) {
p = points[i];
t = i / n;
p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
}
}
return d3_svg_lineBasis(points);
}
function d3_svg_lineDot4(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
}
var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ];
function d3_svg_lineBasisBezier(path, x, y) {
path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
}
function d3_svg_lineSlope(p0, p1) {
return (p1[1] - p0[1]) / (p1[0] - p0[0]);
}
function d3_svg_lineFiniteDifferences(points) {
var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1);
while (++i < j) {
m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2;
}
m[i] = d;
return m;
}
function d3_svg_lineMonotoneTangents(points) {
var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1;
while (++i < j) {
d = d3_svg_lineSlope(points[i], points[i + 1]);
if (abs(d) < ε) {
m[i] = m[i + 1] = 0;
} else {
a = m[i] / d;
b = m[i + 1] / d;
s = a * a + b * b;
if (s > 9) {
s = d * 3 / Math.sqrt(s);
m[i] = s * a;
m[i + 1] = s * b;
}
}
}
i = -1;
while (++i <= j) {
s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
tangents.push([ s || 0, m[i] * s || 0 ]);
}
return tangents;
}
function d3_svg_lineMonotone(points) {
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
}
d3.svg.line.radial = function() {
var line = d3_svg_line(d3_svg_lineRadial);
line.radius = line.x, delete line.x;
line.angle = line.y, delete line.y;
return line;
};
function d3_svg_lineRadial(points) {
var point, i = -1, n = points.length, r, a;
while (++i < n) {
point = points[i];
r = point[0];
a = point[1] + d3_svg_arcOffset;
point[0] = r * Math.cos(a);
point[1] = r * Math.sin(a);
}
return points;
}
function d3_svg_area(projection) {
var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7;
function area(data) {
var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() {
return x;
} : d3_functor(x1), fy1 = y0 === y1 ? function() {
return y;
} : d3_functor(y1), x, y;
function segment() {
segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z");
}
while (++i < n) {
if (defined.call(this, d = data[i], i)) {
points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]);
points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]);
} else if (points0.length) {
segment();
points0 = [];
points1 = [];
}
}
if (points0.length) segment();
return segments.length ? segments.join("") : null;
}
area.x = function(_) {
if (!arguments.length) return x1;
x0 = x1 = _;
return area;
};
area.x0 = function(_) {
if (!arguments.length) return x0;
x0 = _;
return area;
};
area.x1 = function(_) {
if (!arguments.length) return x1;
x1 = _;
return area;
};
area.y = function(_) {
if (!arguments.length) return y1;
y0 = y1 = _;
return area;
};
area.y0 = function(_) {
if (!arguments.length) return y0;
y0 = _;
return area;
};
area.y1 = function(_) {
if (!arguments.length) return y1;
y1 = _;
return area;
};
area.defined = function(_) {
if (!arguments.length) return defined;
defined = _;
return area;
};
area.interpolate = function(_) {
if (!arguments.length) return interpolateKey;
if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
interpolateReverse = interpolate.reverse || interpolate;
L = interpolate.closed ? "M" : "L";
return area;
};
area.tension = function(_) {
if (!arguments.length) return tension;
tension = _;
return area;
};
return area;
}
d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;
d3.svg.area = function() {
return d3_svg_area(d3_identity);
};
d3.svg.area.radial = function() {
var area = d3_svg_area(d3_svg_lineRadial);
area.radius = area.x, delete area.x;
area.innerRadius = area.x0, delete area.x0;
area.outerRadius = area.x1, delete area.x1;
area.angle = area.y, delete area.y;
area.startAngle = area.y0, delete area.y0;
area.endAngle = area.y1, delete area.y1;
return area;
};
d3.svg.chord = function() {
var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle;
function chord(d, i) {
var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i);
return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z";
}
function subgroup(self, f, d, i) {
var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset;
return {
r: r,
a0: a0,
a1: a1,
p0: [ r * Math.cos(a0), r * Math.sin(a0) ],
p1: [ r * Math.cos(a1), r * Math.sin(a1) ]
};
}
function equals(a, b) {
return a.a0 == b.a0 && a.a1 == b.a1;
}
function arc(r, p, a) {
return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p;
}
function curve(r0, p0, r1, p1) {
return "Q 0,0 " + p1;
}
chord.radius = function(v) {
if (!arguments.length) return radius;
radius = d3_functor(v);
return chord;
};
chord.source = function(v) {
if (!arguments.length) return source;
source = d3_functor(v);
return chord;
};
chord.target = function(v) {
if (!arguments.length) return target;
target = d3_functor(v);
return chord;
};
chord.startAngle = function(v) {
if (!arguments.length) return startAngle;
startAngle = d3_functor(v);
return chord;
};
chord.endAngle = function(v) {
if (!arguments.length) return endAngle;
endAngle = d3_functor(v);
return chord;
};
return chord;
};
function d3_svg_chordRadius(d) {
return d.radius;
}
d3.svg.diagonal = function() {
var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection;
function diagonal(d, i) {
var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {
x: p0.x,
y: m
}, {
x: p3.x,
y: m
}, p3 ];
p = p.map(projection);
return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
}
diagonal.source = function(x) {
if (!arguments.length) return source;
source = d3_functor(x);
return diagonal;
};
diagonal.target = function(x) {
if (!arguments.length) return target;
target = d3_functor(x);
return diagonal;
};
diagonal.projection = function(x) {
if (!arguments.length) return projection;
projection = x;
return diagonal;
};
return diagonal;
};
function d3_svg_diagonalProjection(d) {
return [ d.x, d.y ];
}
d3.svg.diagonal.radial = function() {
var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection;
diagonal.projection = function(x) {
return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection;
};
return diagonal;
};
function d3_svg_diagonalRadialProjection(projection) {
return function() {
var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset;
return [ r * Math.cos(a), r * Math.sin(a) ];
};
}
d3.svg.symbol = function() {
var type = d3_svg_symbolType, size = d3_svg_symbolSize;
function symbol(d, i) {
return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i));
}
symbol.type = function(x) {
if (!arguments.length) return type;
type = d3_functor(x);
return symbol;
};
symbol.size = function(x) {
if (!arguments.length) return size;
size = d3_functor(x);
return symbol;
};
return symbol;
};
function d3_svg_symbolSize() {
return 64;
}
function d3_svg_symbolType() {
return "circle";
}
function d3_svg_symbolCircle(size) {
var r = Math.sqrt(size / π);
return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z";
}
var d3_svg_symbols = d3.map({
circle: d3_svg_symbolCircle,
cross: function(size) {
var r = Math.sqrt(size / 5) / 2;
return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z";
},
diamond: function(size) {
var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30;
return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z";
},
square: function(size) {
var r = Math.sqrt(size) / 2;
return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z";
},
"triangle-down": function(size) {
var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;
return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z";
},
"triangle-up": function(size) {
var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;
return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z";
}
});
d3.svg.symbolTypes = d3_svg_symbols.keys();
var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians);
function d3_transition(groups, id) {
d3_subclass(groups, d3_transitionPrototype);
groups.id = id;
return groups;
}
var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit;
d3_transitionPrototype.call = d3_selectionPrototype.call;
d3_transitionPrototype.empty = d3_selectionPrototype.empty;
d3_transitionPrototype.node = d3_selectionPrototype.node;
d3_transitionPrototype.size = d3_selectionPrototype.size;
d3.transition = function(selection) {
return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition();
};
d3.transition.prototype = d3_transitionPrototype;
d3_transitionPrototype.select = function(selector) {
var id = this.id, subgroups = [], subgroup, subnode, node;
selector = d3_selection_selector(selector);
for (var j = -1, m = this.length; ++j < m; ) {
subgroups.push(subgroup = []);
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
d3_transitionNode(subnode, i, id, node.__transition__[id]);
subgroup.push(subnode);
} else {
subgroup.push(null);
}
}
}
return d3_transition(subgroups, id);
};
d3_transitionPrototype.selectAll = function(selector) {
var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition;
selector = d3_selection_selectorAll(selector);
for (var j = -1, m = this.length; ++j < m; ) {
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) {
transition = node.__transition__[id];
subnodes = selector.call(node, node.__data__, i, j);
subgroups.push(subgroup = []);
for (var k = -1, o = subnodes.length; ++k < o; ) {
if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition);
subgroup.push(subnode);
}
}
}
}
return d3_transition(subgroups, id);
};
d3_transitionPrototype.filter = function(filter) {
var subgroups = [], subgroup, group, node;
if (typeof filter !== "function") filter = d3_selection_filter(filter);
for (var j = 0, m = this.length; j < m; j++) {
subgroups.push(subgroup = []);
for (var group = this[j], i = 0, n = group.length; i < n; i++) {
if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
subgroup.push(node);
}
}
}
return d3_transition(subgroups, this.id);
};
d3_transitionPrototype.tween = function(name, tween) {
var id = this.id;
if (arguments.length < 2) return this.node().__transition__[id].tween.get(name);
return d3_selection_each(this, tween == null ? function(node) {
node.__transition__[id].tween.remove(name);
} : function(node) {
node.__transition__[id].tween.set(name, tween);
});
};
function d3_transition_tween(groups, name, value, tween) {
var id = groups.id;
return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) {
node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j)));
} : (value = tween(value), function(node) {
node.__transition__[id].tween.set(name, value);
}));
}
d3_transitionPrototype.attr = function(nameNS, value) {
if (arguments.length < 2) {
for (value in nameNS) this.attr(value, nameNS[value]);
return this;
}
var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);
function attrNull() {
this.removeAttribute(name);
}
function attrNullNS() {
this.removeAttributeNS(name.space, name.local);
}
function attrTween(b) {
return b == null ? attrNull : (b += "", function() {
var a = this.getAttribute(name), i;
return a !== b && (i = interpolate(a, b), function(t) {
this.setAttribute(name, i(t));
});
});
}
function attrTweenNS(b) {
return b == null ? attrNullNS : (b += "", function() {
var a = this.getAttributeNS(name.space, name.local), i;
return a !== b && (i = interpolate(a, b), function(t) {
this.setAttributeNS(name.space, name.local, i(t));
});
});
}
return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween);
};
d3_transitionPrototype.attrTween = function(nameNS, tween) {
var name = d3.ns.qualify(nameNS);
function attrTween(d, i) {
var f = tween.call(this, d, i, this.getAttribute(name));
return f && function(t) {
this.setAttribute(name, f(t));
};
}
function attrTweenNS(d, i) {
var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
return f && function(t) {
this.setAttributeNS(name.space, name.local, f(t));
};
}
return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween);
};
d3_transitionPrototype.style = function(name, value, priority) {
var n = arguments.length;
if (n < 3) {
if (typeof name !== "string") {
if (n < 2) value = "";
for (priority in name) this.style(priority, name[priority], value);
return this;
}
priority = "";
}
function styleNull() {
this.style.removeProperty(name);
}
function styleString(b) {
return b == null ? styleNull : (b += "", function() {
var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i;
return a !== b && (i = d3_interpolate(a, b), function(t) {
this.style.setProperty(name, i(t), priority);
});
});
}
return d3_transition_tween(this, "style." + name, value, styleString);
};
d3_transitionPrototype.styleTween = function(name, tween, priority) {
if (arguments.length < 3) priority = "";
function styleTween(d, i) {
var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name));
return f && function(t) {
this.style.setProperty(name, f(t), priority);
};
}
return this.tween("style." + name, styleTween);
};
d3_transitionPrototype.text = function(value) {
return d3_transition_tween(this, "text", value, d3_transition_text);
};
function d3_transition_text(b) {
if (b == null) b = "";
return function() {
this.textContent = b;
};
}
d3_transitionPrototype.remove = function() {
return this.each("end.transition", function() {
var p;
if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this);
});
};
d3_transitionPrototype.ease = function(value) {
var id = this.id;
if (arguments.length < 1) return this.node().__transition__[id].ease;
if (typeof value !== "function") value = d3.ease.apply(d3, arguments);
return d3_selection_each(this, function(node) {
node.__transition__[id].ease = value;
});
};
d3_transitionPrototype.delay = function(value) {
var id = this.id;
if (arguments.length < 1) return this.node().__transition__[id].delay;
return d3_selection_each(this, typeof value === "function" ? function(node, i, j) {
node.__transition__[id].delay = +value.call(node, node.__data__, i, j);
} : (value = +value, function(node) {
node.__transition__[id].delay = value;
}));
};
d3_transitionPrototype.duration = function(value) {
var id = this.id;
if (arguments.length < 1) return this.node().__transition__[id].duration;
return d3_selection_each(this, typeof value === "function" ? function(node, i, j) {
node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j));
} : (value = Math.max(1, value), function(node) {
node.__transition__[id].duration = value;
}));
};
d3_transitionPrototype.each = function(type, listener) {
var id = this.id;
if (arguments.length < 2) {
var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId;
d3_transitionInheritId = id;
d3_selection_each(this, function(node, i, j) {
d3_transitionInherit = node.__transition__[id];
type.call(node, node.__data__, i, j);
});
d3_transitionInherit = inherit;
d3_transitionInheritId = inheritId;
} else {
d3_selection_each(this, function(node) {
var transition = node.__transition__[id];
(transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener);
});
}
return this;
};
d3_transitionPrototype.transition = function() {
var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition;
for (var j = 0, m = this.length; j < m; j++) {
subgroups.push(subgroup = []);
for (var group = this[j], i = 0, n = group.length; i < n; i++) {
if (node = group[i]) {
transition = Object.create(node.__transition__[id0]);
transition.delay += transition.duration;
d3_transitionNode(node, i, id1, transition);
}
subgroup.push(node);
}
}
return d3_transition(subgroups, id1);
};
function d3_transitionNode(node, i, id, inherit) {
var lock = node.__transition__ || (node.__transition__ = {
active: 0,
count: 0
}), transition = lock[id];
if (!transition) {
var time = inherit.time;
transition = lock[id] = {
tween: new d3_Map(),
time: time,
ease: inherit.ease,
delay: inherit.delay,
duration: inherit.duration
};
++lock.count;
d3.timer(function(elapsed) {
var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, timer = d3_timer_active, tweened = [];
timer.t = delay + time;
if (delay <= elapsed) return start(elapsed - delay);
timer.c = start;
function start(elapsed) {
if (lock.active > id) return stop();
lock.active = id;
transition.event && transition.event.start.call(node, d, i);
transition.tween.forEach(function(key, value) {
if (value = value.call(node, d, i)) {
tweened.push(value);
}
});
d3.timer(function() {
timer.c = tick(elapsed || 1) ? d3_true : tick;
return 1;
}, 0, time);
}
function tick(elapsed) {
if (lock.active !== id) return stop();
var t = elapsed / duration, e = ease(t), n = tweened.length;
while (n > 0) {
tweened[--n].call(node, e);
}
if (t >= 1) {
transition.event && transition.event.end.call(node, d, i);
return stop();
}
}
function stop() {
if (--lock.count) delete lock[id]; else delete node.__transition__;
return 1;
}
}, 0, time);
}
}
d3.svg.axis = function() {
var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_;
function axis(g) {
g.each(function() {
var g = d3.select(this);
var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy();
var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickTransform;
var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"),
d3.transition(path));
tickEnter.append("line");
tickEnter.append("text");
var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text");
switch (orient) {
case "bottom":
{
tickTransform = d3_svg_axisX;
lineEnter.attr("y2", innerTickSize);
textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding);
lineUpdate.attr("x2", 0).attr("y2", innerTickSize);
textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding);
text.attr("dy", ".71em").style("text-anchor", "middle");
pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize);
break;
}
case "top":
{
tickTransform = d3_svg_axisX;
lineEnter.attr("y2", -innerTickSize);
textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding));
lineUpdate.attr("x2", 0).attr("y2", -innerTickSize);
textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding));
text.attr("dy", "0em").style("text-anchor", "middle");
pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize);
break;
}
case "left":
{
tickTransform = d3_svg_axisY;
lineEnter.attr("x2", -innerTickSize);
textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding));
lineUpdate.attr("x2", -innerTickSize).attr("y2", 0);
textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0);
text.attr("dy", ".32em").style("text-anchor", "end");
pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize);
break;
}
case "right":
{
tickTransform = d3_svg_axisY;
lineEnter.attr("x2", innerTickSize);
textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding);
lineUpdate.attr("x2", innerTickSize).attr("y2", 0);
textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0);
text.attr("dy", ".32em").style("text-anchor", "start");
pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize);
break;
}
}
if (scale1.rangeBand) {
var x = scale1, dx = x.rangeBand() / 2;
scale0 = scale1 = function(d) {
return x(d) + dx;
};
} else if (scale0.rangeBand) {
scale0 = scale1;
} else {
tickExit.call(tickTransform, scale1);
}
tickEnter.call(tickTransform, scale0);
tickUpdate.call(tickTransform, scale1);
});
}
axis.scale = function(x) {
if (!arguments.length) return scale;
scale = x;
return axis;
};
axis.orient = function(x) {
if (!arguments.length) return orient;
orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient;
return axis;
};
axis.ticks = function() {
if (!arguments.length) return tickArguments_;
tickArguments_ = arguments;
return axis;
};
axis.tickValues = function(x) {
if (!arguments.length) return tickValues;
tickValues = x;
return axis;
};
axis.tickFormat = function(x) {
if (!arguments.length) return tickFormat_;
tickFormat_ = x;
return axis;
};
axis.tickSize = function(x) {
var n = arguments.length;
if (!n) return innerTickSize;
innerTickSize = +x;
outerTickSize = +arguments[n - 1];
return axis;
};
axis.innerTickSize = function(x) {
if (!arguments.length) return innerTickSize;
innerTickSize = +x;
return axis;
};
axis.outerTickSize = function(x) {
if (!arguments.length) return outerTickSize;
outerTickSize = +x;
return axis;
};
axis.tickPadding = function(x) {
if (!arguments.length) return tickPadding;
tickPadding = +x;
return axis;
};
axis.tickSubdivide = function() {
return arguments.length && axis;
};
return axis;
};
var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = {
top: 1,
right: 1,
bottom: 1,
left: 1
};
function d3_svg_axisX(selection, x) {
selection.attr("transform", function(d) {
return "translate(" + x(d) + ",0)";
});
}
function d3_svg_axisY(selection, y) {
selection.attr("transform", function(d) {
return "translate(0," + y(d) + ")";
});
}
d3.svg.brush = function() {
var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0];
function brush(g) {
g.each(function() {
var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart);
var background = g.selectAll(".background").data([ 0 ]);
background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair");
g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move");
var resize = g.selectAll(".resize").data(resizes, d3_identity);
resize.exit().remove();
resize.enter().append("g").attr("class", function(d) {
return "resize " + d;
}).style("cursor", function(d) {
return d3_svg_brushCursor[d];
}).append("rect").attr("x", function(d) {
return /[ew]$/.test(d) ? -3 : null;
}).attr("y", function(d) {
return /^[ns]/.test(d) ? -3 : null;
}).attr("width", 6).attr("height", 6).style("visibility", "hidden");
resize.style("display", brush.empty() ? "none" : null);
var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range;
if (x) {
range = d3_scaleRange(x);
backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]);
redrawX(gUpdate);
}
if (y) {
range = d3_scaleRange(y);
backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]);
redrawY(gUpdate);
}
redraw(gUpdate);
});
}
brush.event = function(g) {
g.each(function() {
var event_ = event.of(this, arguments), extent1 = {
x: xExtent,
y: yExtent,
i: xExtentDomain,
j: yExtentDomain
}, extent0 = this.__chart__ || extent1;
this.__chart__ = extent1;
if (d3_transitionInheritId) {
d3.select(this).transition().each("start.brush", function() {
xExtentDomain = extent0.i;
yExtentDomain = extent0.j;
xExtent = extent0.x;
yExtent = extent0.y;
event_({
type: "brushstart"
});
}).tween("brush:brush", function() {
var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y);
xExtentDomain = yExtentDomain = null;
return function(t) {
xExtent = extent1.x = xi(t);
yExtent = extent1.y = yi(t);
event_({
type: "brush",
mode: "resize"
});
};
}).each("end.brush", function() {
xExtentDomain = extent1.i;
yExtentDomain = extent1.j;
event_({
type: "brush",
mode: "resize"
});
event_({
type: "brushend"
});
});
} else {
event_({
type: "brushstart"
});
event_({
type: "brush",
mode: "resize"
});
event_({
type: "brushend"
});
}
});
};
function redraw(g) {
g.selectAll(".resize").attr("transform", function(d) {
return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")";
});
}
function redrawX(g) {
g.select(".extent").attr("x", xExtent[0]);
g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]);
}
function redrawY(g) {
g.select(".extent").attr("y", yExtent[0]);
g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]);
}
function brushstart() {
var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset;
var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup);
if (d3.event.changedTouches) {
w.on("touchmove.brush", brushmove).on("touchend.brush", brushend);
} else {
w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend);
}
g.interrupt().selectAll("*").interrupt();
if (dragging) {
origin[0] = xExtent[0] - origin[0];
origin[1] = yExtent[0] - origin[1];
} else if (resizing) {
var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing);
offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ];
origin[0] = xExtent[ex];
origin[1] = yExtent[ey];
} else if (d3.event.altKey) center = origin.slice();
g.style("pointer-events", "none").selectAll(".resize").style("display", null);
d3.select("body").style("cursor", eventTarget.style("cursor"));
event_({
type: "brushstart"
});
brushmove();
function keydown() {
if (d3.event.keyCode == 32) {
if (!dragging) {
center = null;
origin[0] -= xExtent[1];
origin[1] -= yExtent[1];
dragging = 2;
}
d3_eventPreventDefault();
}
}
function keyup() {
if (d3.event.keyCode == 32 && dragging == 2) {
origin[0] += xExtent[1];
origin[1] += yExtent[1];
dragging = 0;
d3_eventPreventDefault();
}
}
function brushmove() {
var point = d3.mouse(target), moved = false;
if (offset) {
point[0] += offset[0];
point[1] += offset[1];
}
if (!dragging) {
if (d3.event.altKey) {
if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ];
origin[0] = xExtent[+(point[0] < center[0])];
origin[1] = yExtent[+(point[1] < center[1])];
} else center = null;
}
if (resizingX && move1(point, x, 0)) {
redrawX(g);
moved = true;
}
if (resizingY && move1(point, y, 1)) {
redrawY(g);
moved = true;
}
if (moved) {
redraw(g);
event_({
type: "brush",
mode: dragging ? "move" : "resize"
});
}
}
function move1(point, scale, i) {
var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max;
if (dragging) {
r0 -= position;
r1 -= size + position;
}
min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i];
if (dragging) {
max = (min += position) + size;
} else {
if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min));
if (position < min) {
max = min;
min = position;
} else {
max = position;
}
}
if (extent[0] != min || extent[1] != max) {
if (i) yExtentDomain = null; else xExtentDomain = null;
extent[0] = min;
extent[1] = max;
return true;
}
}
function brushend() {
brushmove();
g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null);
d3.select("body").style("cursor", null);
w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null);
dragRestore();
event_({
type: "brushend"
});
}
}
brush.x = function(z) {
if (!arguments.length) return x;
x = z;
resizes = d3_svg_brushResizes[!x << 1 | !y];
return brush;
};
brush.y = function(z) {
if (!arguments.length) return y;
y = z;
resizes = d3_svg_brushResizes[!x << 1 | !y];
return brush;
};
brush.clamp = function(z) {
if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null;
if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z;
return brush;
};
brush.extent = function(z) {
var x0, x1, y0, y1, t;
if (!arguments.length) {
if (x) {
if (xExtentDomain) {
x0 = xExtentDomain[0], x1 = xExtentDomain[1];
} else {
x0 = xExtent[0], x1 = xExtent[1];
if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1);
if (x1 < x0) t = x0, x0 = x1, x1 = t;
}
}
if (y) {
if (yExtentDomain) {
y0 = yExtentDomain[0], y1 = yExtentDomain[1];
} else {
y0 = yExtent[0], y1 = yExtent[1];
if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1);
if (y1 < y0) t = y0, y0 = y1, y1 = t;
}
}
return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ];
}
if (x) {
x0 = z[0], x1 = z[1];
if (y) x0 = x0[0], x1 = x1[0];
xExtentDomain = [ x0, x1 ];
if (x.invert) x0 = x(x0), x1 = x(x1);
if (x1 < x0) t = x0, x0 = x1, x1 = t;
if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ];
}
if (y) {
y0 = z[0], y1 = z[1];
if (x) y0 = y0[1], y1 = y1[1];
yExtentDomain = [ y0, y1 ];
if (y.invert) y0 = y(y0), y1 = y(y1);
if (y1 < y0) t = y0, y0 = y1, y1 = t;
if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ];
}
return brush;
};
brush.clear = function() {
if (!brush.empty()) {
xExtent = [ 0, 0 ], yExtent = [ 0, 0 ];
xExtentDomain = yExtentDomain = null;
}
return brush;
};
brush.empty = function() {
return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1];
};
return d3.rebind(brush, event, "on");
};
var d3_svg_brushCursor = {
n: "ns-resize",
e: "ew-resize",
s: "ns-resize",
w: "ew-resize",
nw: "nwse-resize",
ne: "nesw-resize",
se: "nwse-resize",
sw: "nesw-resize"
};
var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ];
var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat;
var d3_time_formatUtc = d3_time_format.utc;
var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ");
d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso;
function d3_time_formatIsoNative(date) {
return date.toISOString();
}
d3_time_formatIsoNative.parse = function(string) {
var date = new Date(string);
return isNaN(date) ? null : date;
};
d3_time_formatIsoNative.toString = d3_time_formatIso.toString;
d3_time.second = d3_time_interval(function(date) {
return new d3_date(Math.floor(date / 1e3) * 1e3);
}, function(date, offset) {
date.setTime(date.getTime() + Math.floor(offset) * 1e3);
}, function(date) {
return date.getSeconds();
});
d3_time.seconds = d3_time.second.range;
d3_time.seconds.utc = d3_time.second.utc.range;
d3_time.minute = d3_time_interval(function(date) {
return new d3_date(Math.floor(date / 6e4) * 6e4);
}, function(date, offset) {
date.setTime(date.getTime() + Math.floor(offset) * 6e4);
}, function(date) {
return date.getMinutes();
});
d3_time.minutes = d3_time.minute.range;
d3_time.minutes.utc = d3_time.minute.utc.range;
d3_time.hour = d3_time_interval(function(date) {
var timezone = date.getTimezoneOffset() / 60;
return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5);
}, function(date, offset) {
date.setTime(date.getTime() + Math.floor(offset) * 36e5);
}, function(date) {
return date.getHours();
});
d3_time.hours = d3_time.hour.range;
d3_time.hours.utc = d3_time.hour.utc.range;
d3_time.month = d3_time_interval(function(date) {
date = d3_time.day(date);
date.setDate(1);
return date;
}, function(date, offset) {
date.setMonth(date.getMonth() + offset);
}, function(date) {
return date.getMonth();
});
d3_time.months = d3_time.month.range;
d3_time.months.utc = d3_time.month.utc.range;
function d3_time_scale(linear, methods, format) {
function scale(x) {
return linear(x);
}
scale.invert = function(x) {
return d3_time_scaleDate(linear.invert(x));
};
scale.domain = function(x) {
if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
linear.domain(x);
return scale;
};
function tickMethod(extent, count) {
var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target);
return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) {
return d / 31536e6;
}), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i];
}
scale.nice = function(interval, skip) {
var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval);
if (method) interval = method[0], skip = method[1];
function skipped(date) {
return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length;
}
return scale.domain(d3_scale_nice(domain, skip > 1 ? {
floor: function(date) {
while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1);
return date;
},
ceil: function(date) {
while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1);
return date;
}
} : interval));
};
scale.ticks = function(interval, skip) {
var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ {
range: interval
}, skip ];
if (method) interval = method[0], skip = method[1];
return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip);
};
scale.tickFormat = function() {
return format;
};
scale.copy = function() {
return d3_time_scale(linear.copy(), methods, format);
};
return d3_scale_linearRebind(scale, linear);
}
function d3_time_scaleDate(t) {
return new Date(t);
}
var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ];
var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ];
var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) {
return d.getMilliseconds();
} ], [ ":%S", function(d) {
return d.getSeconds();
} ], [ "%I:%M", function(d) {
return d.getMinutes();
} ], [ "%I %p", function(d) {
return d.getHours();
} ], [ "%a %d", function(d) {
return d.getDay() && d.getDate() != 1;
} ], [ "%b %d", function(d) {
return d.getDate() != 1;
} ], [ "%B", function(d) {
return d.getMonth();
} ], [ "%Y", d3_true ] ]);
var d3_time_scaleMilliseconds = {
range: function(start, stop, step) {
return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate);
},
floor: d3_identity,
ceil: d3_identity
};
d3_time_scaleLocalMethods.year = d3_time.year;
d3_time.scale = function() {
return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);
};
var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) {
return [ m[0].utc, m[1] ];
});
var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) {
return d.getUTCMilliseconds();
} ], [ ":%S", function(d) {
return d.getUTCSeconds();
} ], [ "%I:%M", function(d) {
return d.getUTCMinutes();
} ], [ "%I %p", function(d) {
return d.getUTCHours();
} ], [ "%a %d", function(d) {
return d.getUTCDay() && d.getUTCDate() != 1;
} ], [ "%b %d", function(d) {
return d.getUTCDate() != 1;
} ], [ "%B", function(d) {
return d.getUTCMonth();
} ], [ "%Y", d3_true ] ]);
d3_time_scaleUtcMethods.year = d3_time.year.utc;
d3_time.scale.utc = function() {
return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat);
};
d3.text = d3_xhrType(function(request) {
return request.responseText;
});
d3.json = function(url, callback) {
return d3_xhr(url, "application/json", d3_json, callback);
};
function d3_json(request) {
return JSON.parse(request.responseText);
}
d3.html = function(url, callback) {
return d3_xhr(url, "text/html", d3_html, callback);
};
function d3_html(request) {
var range = d3_document.createRange();
range.selectNode(d3_document.body);
return range.createContextualFragment(request.responseText);
}
d3.xml = d3_xhrType(function(request) {
return request.responseXML;
});
if (typeof define === "function" && define.amd) define(d3); else if (typeof module === "object" && module.exports) module.exports = d3;
this.d3 = d3;
}();
================================================
FILE: examples/autocomplete/autocomplete.html
================================================
Rx for JavaScript Rocks!
RxJS Autocomplete example
Example to show combining input events such as keyup with Ajax requests
================================================
FILE: examples/autocomplete/autocomplete.js
================================================
(function (global, $, Rx) {
// Search Wikipedia for a given term
function searchWikipedia (term) {
return $.ajax({
url: 'http://en.wikipedia.org/w/api.php',
dataType: 'jsonp',
data: {
action: 'opensearch',
format: 'json',
search: term
}
}).promise();
}
function main() {
var $input = $('#textInput'),
$results = $('#results');
// Get all distinct key up events from the input and only fire if long enough and distinct
var keyup = Rx.Observable.fromEvent($input, 'keyup')
.map(function (e) {
return e.target.value; // Project the text from the input
})
.filter(function (text) {
return text.length > 2; // Only if the text is longer than 2 characters
})
.debounce(750 /* Pause for 750ms */ )
.distinctUntilChanged(); // Only if the value has changed
var searcher = keyup.flatMapLatest(searchWikipedia);
searcher.subscribe(
function (data) {
$results
.empty()
.append ($.map(data[1], function (v) { return $('
').text(v); }));
},
function (error) {
$results
.empty()
.append($('
Example to show backpressure with lossy and loss-less pausable observables
Lossy Pausable using .pauseableBuffered for mouse movements
================================================
FILE: examples/backpressure/index.js
================================================
(function () {
function main() {
var fromEvent = Rx.Observable.fromEvent;
function isChecked(x) { return x.checked; }
function notChecked(x) { return !x.checked; }
var losslessResults = document.getElementById('losslessResults');
var losslessToggle = document.getElementById('losslessToggle');
function logInput(text) {
var li = document.createElement('li');
li.innerHTML = text;
losslessResults.appendChild(li);
}
var mousemove = fromEvent(document, 'mousemove')
.map(function (e) {
return 'clientX: ' + e.clientX + ', clientY: ' + e.clientY;
})
.pausableBuffered();
// Lossless
var losslessClick = fromEvent(losslessToggle, 'click')
.map(function (e) { return e.target.checked; })
losslessClick.subscribe(function (checked) {
if (checked) {
mousemove.resume();
} else {
mousemove.pause();
}
})
mousemove.subscribe(function (text) {
logInput(text);
});
}
window.onload = main;
}());
================================================
FILE: examples/backpressure/readme.md
================================================
================================================
FILE: examples/canvaspaint/canvaspaint.css
================================================
canvas {
background-color: #cccccb;
}
html {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
}
================================================
FILE: examples/canvaspaint/canvaspaint.html
================================================
Rx for JavaScript Rocks!
RxJS Canvas Paint Example
Example to show combining mouse events to draw on an HTML5 Canvas
================================================
FILE: examples/canvaspaint/canvaspaint.js
================================================
(function (window, document, Rx) {
Rx.DOM = { };
['mousemove', 'mouseup', 'mousedown', 'click'].forEach(function (name) {
Rx.DOM[name] = function (element, selector) {
return Rx.Observable.fromEvent(element, name, selector);
};
});
Rx.DOM.ready = function () {
return Rx.Observable.create(function (o) {
function handler() {
o.onNext();
o.onCompleted();
}
var added = false;
if (document.readyState === 'complete') {
handler();
} else {
document.addEventListener('DOMContentLoaded', handler, false);
added = true;
return Rx.Disposable.create(function () {
added && document.removeEventListener('DOMContentLoaded', handler, false);
});
}
}).take(1);
};
// Calcualte offset either layerX/Y or offsetX/Y
function getOffset(event) {
return {
offsetX: event.offsetX === undefined ? event.layerX : event.offsetX,
offsetY: event.offsetY === undefined ? event.layerY : event.offsetY
};
}
function intialize () {
var canvas = document.getElementById('tutorial');
var colorchart = document.querySelectorAll('#colorchart tr td');
var ctx = canvas.getContext('2d');
ctx.beginPath();
// Get mouse events
var mouseMoves = Rx.DOM.mousemove(canvas),
mouseDowns = Rx.DOM.mousedown(canvas),
mouseUps = Rx.DOM.mouseup(canvas);
// Get the table events
var colorValues = Rx.DOM.click(colorchart)
.tap(function () { ctx.beginPath(); })
.map(function (e) { return e.target.bgColor; })
.startWith('#000000');
// Calculate difference between two mouse moves
var mouseDiffs = mouseMoves.zip(mouseMoves.skip(1), function (x, y) {
return { first: getOffset(x), second: getOffset(y) };
});
// Get merge together both mouse up and mouse down
var mouseButton = mouseDowns.map(true)
.merge(mouseUps.map(false));
// Paint if the mouse is down
var paint = mouseButton.flatMapLatest(function (down) { return down ? mouseDiffs : Rx.Observable.never(); })
.combineLatest(colorValues, function (pos, color) {
return { pos : pos, color: color };
});
// Update the canvas
paint.subscribe(function (x) {
ctx.strokeStyle = x.color;
ctx.moveTo(x.pos.first.offsetX, x.pos.first.offsetY);
ctx.lineTo(x.pos.second.offsetX, x.pos.second.offsetY);
ctx.stroke();
});
}
Rx.DOM.ready().subscribe(intialize);
}(window, document, Rx));
================================================
FILE: examples/canvaspaint/excanvas_src.js
================================================
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
// width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
// Quirks mode will draw the canvas using border-box. Either change your
// doctype to HTML5
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.
// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {
(function() {
// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;
var abs = m.abs;
var sqrt = m.sqrt;
var msie_ver = getIEVersion();
function getIEVersion() {
var ver = -1;
if(navigator != null && navigator.appName == 'Microsoft Internet Explorer') {
var regEx = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if(regEx.exec(navigator.userAgent) != null) ver = parseInt(RegExp.$1);
}
return ver;
}
// this is used for sub pixel precision
var Z = 10;
var Z2 = Z / 2;
/**
* This funtion is assigned to the
================================================
FILE: examples/longstacktraces/readme.md
================================================
================================================
FILE: examples/mario/index.css
================================================
body {
font-family: Arial;
font-size: 14px;
color: #555;
padding: 20px;
margin: 0;
background-color: rgba(174, 238, 238, 1);
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
nav ul li {
margin: 4px 0;
}
a {
text-decoration: none;
color: inherit;
font-weight: bold;
}
#grass {
position: fixed;
background-color: rgba(74, 163, 41, 1);
left: 0;
right: 0;
bottom: 0;
height: 60px;
}
#mario {
position: fixed;
}
================================================
FILE: examples/mario/index.html
================================================
Mario in RxJS Rocks!
================================================
FILE: examples/pacman-unicode/index.js
================================================
// Originally from https://github.com/eguneys/pacman-unicode/blob/master/app/scripts/main.js
(function () {
function ready() {
return Rx.Observable.create(function (observer) {
var addedHandlers = false;
function handler () {
observer.onNext();
observer.onCompleted();
}
if (document.readyState === 'complete') {
setTimeout(handler, 0);
} else {
addedHandlers = true;
document.addEventListener( 'DOMContentLoaded', handler, false );
}
return function () {
if (!addedHandlers) { return; }
document.removeEventListener( 'DOMContentLoaded', handler, false );
};
});
};
ready().subscribe(function() {
restartGame(document.querySelector('.game-area'));
});
function restartGame(parent, hs) {
var game = new PacmanGame(parent, hs);
var moveStream = Rx.Observable.create(function(observer) {
game.onPacmanMove = function(moveV) {
observer.onNext(moveV);
};
}).publish().refCount();
moveStream.subscribe(function(moveV) {
if (!moveV) {
restartGame(parent, game.highScore);
return;
}
game.movePacman(moveV);
});
var spawnStream = Rx.Observable.of(
PacmanGame.GhostColors.ORANGE,
PacmanGame.GhostColors.BLUE,
PacmanGame.GhostColors.GREEN,
PacmanGame.GhostColors.PURPLE,
PacmanGame.GhostColors.WHITE
)
.flatMap(function (x) { return Rx.Observable.timer(800).map(x); })
.delay(2500);
spawnStream.subscribe(function(ghost) {
game.spawnGhost(ghost);
});
var ghostStream = Rx.Observable.interval(1000);
ghostStream.subscribe(function() {
game.updateGhosts();
});
Rx.Observable.merge(moveStream, ghostStream).subscribe(function() {
game.tick();
});
game.start();
}
}());
================================================
FILE: examples/pacman-unicode/main.css
================================================
body{
background:#fafafa;
font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#333}
.hero-unit{margin:50px auto 0;width:300px;font-size:18px;font-weight:200;line-height:30px;background-color:#eee;border-radius:6px;padding:60px}
.hero-unit h1{font-size:60px;line-height:1;letter-spacing:-1px}
.browsehappy{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}
================================================
FILE: examples/pacman-unicode/pacman.js
================================================
// Originally from https://github.com/eguneys/pacman-unicode/blob/master/app/scripts/pacman.js
(function () {
'use strict';
function PacmanGame(parent, hs) {
this.parent = parent;
this.term = null;
this.termConfig = {
hud: { x: 3, y: 1 },
gameArea: { x: 3, y: 3 }
};
this.gameOver = true;
this.score = 0;
this.highScore = hs || 0;
this.totalPoints = 0;
this.countPoints = 0;
this.p1 = null;
this.ghosts = null;
this.map = null;
this.TilePacmanLeft = [new ut.Tile('>', 255, 255, 0), new ut.Tile('-', 255, 255, 0)];
this.TilePacmanRight = [new ut.Tile('<', 255, 255, 0), new ut.Tile('-', 255, 255, 0)];
this.TilePacmanUp = [new ut.Tile('V', 255, 255, 0), new ut.Tile('|', 255, 255, 0)];
this.TilePacmanDown = [new ut.Tile('^', 255, 255, 0), new ut.Tile('|', 255, 255, 0)];
this.TilePoint = new ut.Tile('▪', 150, 0, 150);
this.TileBigP = new ut.Tile('O', 150, 0, 150);
this.TileWall = new ut.Tile(' ', 0, 0, 0, 100, 100, 100);
this.TileEmpty = new ut.Tile(' ', 100, 100, 100);
var hudbg = PacmanGame.HudColors.BG;
this.TileHudBG = new ut.Tile(' ', 0, 0, 0, hudbg.r, hudbg.g, hudbg.b);
this.onPacmanMove = null;
}
PacmanGame.HudColors = {
BG: { r: 94, g: 39, b: 40 }
};
PacmanGame.GhostColors = {
ORANGE: 1,
BLUE: 2,
GREEN: 3,
PURPLE: 4,
WHITE: 5
};
PacmanGame.PacmanTiles = {
WALL: '#',
POINT: '.',
BIGP: 'o',
'EMPTY': ' '
};
PacmanGame.prototype.generateMap = function() {
this.p1 = { x: 14, y: 12,
tile: this.TilePacmanLeft[0]
};
this.ghosts = [];
this.map = [
'############################',
'#o...........##...........o#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#..........................#',
'#.####.#.##########.#.####.#',
'#......#.....##.....#......#',
'######.#####.##.#####.######',
' #.#............#.# ',
'######.#.#### ####.#.######',
'.........# #.........',
'######.#.##########.#.######',
' #.#............#.# ',
'######.#.##########.#.######',
'#............##............#',
'#.####.#####.##.#####.####.#',
'#...##................##...#',
'###.##.#.##########.#.##.###',
'#......#.....##.....#......#',
'#.##########.##.##########.#',
'#o........................o#',
'############################'
];
var totalPoints = 0;
this.map.forEach(function(s) {
totalPoints += s.split('.').length - 1;
});
this.totalPoints = totalPoints;
this.wrapPos = [
{ x: -1, y: 10,
wrapTo: { x: 27, y: 10 }
},
{ x: 28, y: 10,
wrapTo: { x: 0, y: 10 }
}
];
};
PacmanGame.prototype.getGhostTile = function(color) {
var tileChar = 'X';
var tile;
switch (color) {
case PacmanGame.GhostColors.ORANGE:
tile = new ut.Tile(tileChar, 150, 75, 0);
break;
case PacmanGame.GhostColors.BLUE:
tile = new ut.Tile(tileChar, 0, 0, 100);
break;
case PacmanGame.GhostColors.GREEN:
tile = new ut.Tile(tileChar, 0, 100, 0);
break;
case PacmanGame.GhostColors.PURPLE:
tile = new ut.Tile(tileChar, 100, 0, 100);
break;
case PacmanGame.GhostColors.WHITE:
tile = new ut.Tile(tileChar, 255, 255, 255);
break;
}
return tile;
};
PacmanGame.prototype.getPacmanTile = function(x, y) {
var t = '';
try { t = this.map[y][x]; }
catch(err) { return ut.NULLTILE; }
switch(t) {
case PacmanGame.PacmanTiles.POINT:
return this.TilePoint;
case PacmanGame.PacmanTiles.BIGP:
return this.TileBigP;
case PacmanGame.PacmanTiles.WALL:
return this.TileWall;
case PacmanGame.PacmanTiles.EMPTY:
return this.TileEmpty;
default:
return ut.NULLTILE;
}
};
PacmanGame.prototype.setPacmanTile = function(x, y, tile) {
var row = this.map[y];
this.map[y] = row.substr(0, x) + tile + row.substr(x + 1);
};
PacmanGame.prototype.setGameOver = function() {
this.p1.tile = new ut.Tile('Ⴖ', 255, 255, 255);
this.gameOver = true;
this.highScore = Math.max(this.highScore, this.score);
};
PacmanGame.prototype.putHud = function() {
var base = this.termConfig.hud;
for (var x = 0; x < this.map[0].length; x++) {
for (var y = 0; y < 2; y++) {
this.term.put(this.TileHudBG, base.x + x, base.y + y);
}
}
var hudbg = PacmanGame.HudColors.BG;
var halfLength = this.map[0].length / 2;
this.term.putString("High Score", base.x + halfLength, base.y, 255, 255, 255, hudbg.r, hudbg.g, hudbg.b);
this.term.putString(this.score.toString(), base.x + 2, base.y + 1, 255, 255, 255, hudbg.r, hudbg.g, hudbg.b);
this.term.putString(this.highScore.toString(), base.x + halfLength, base.y + 1, 255, 255, 255, hudbg.r, hudbg.g, hudbg.b);
if (this.gameOver) {
var mapLength = this.map.length;
this.term.putString("Game Over", base.x, base.y + mapLength + 2, 255, 255, 255, hudbg.r, hudbg.g, hudbg.b);
this.term.putString("Space to Restart", base.x, base.y + mapLength + 3, 255, 255, 255, hudbg.r, hudbg.g, hudbg.b);
}
};
PacmanGame.prototype.putTiles = function() {
var base = this.termConfig.gameArea;
for (var y = 0; y < this.map.length; y++) {
for (var x = 0; x< this.map[0].length; x++) {
this.term.put(this.getPacmanTile(x, y), base.x + x, base.y + y);
}
}
};
PacmanGame.prototype.putMovables = function() {
var base = this.termConfig.gameArea;
this.term.put(this.p1.tile, base.x + this.p1.x, base.y + this.p1.y);
for (var i in this.ghosts) {
var ghost = this.ghosts[i];
this.term.put(ghost.tile, base.x + ghost.x, base.y + ghost.y);
}
};
PacmanGame.prototype.movePacman = function(p1V) {
var p1 = { x: this.p1.x + p1V.x, y: this.p1.y + p1V.y,
tile: this.TilePacmanDown
};
if (this.gameOver) {
return;
}
if (!this.canMoveTo(p1.x, p1.y)) {
var wrapPos = this.findWrapPos(p1.x, p1.y);
if (wrapPos) {
p1.x = wrapPos.x;
p1.y = wrapPos.y;
} else {
return;
}
}
if (p1V.x < 0) {
p1.tile = this.TilePacmanLeft;
} else if (p1V.x > 0) {
p1.tile = this.TilePacmanRight;
} else if (p1V.y < 0) {
p1.tile = this.TilePacmanUp;
}
if (p1.tile[0] === this.p1.tile) {
p1.tile = p1.tile[1];
} else {
p1.tile = p1.tile[0];
}
this.p1 = p1;
};
PacmanGame.prototype.spawnGhost = function(color) {
var ghost = {
x: 14, y: 10,
tile: this.getGhostTile(color),
v: { x: 0, y: -1 }
};
this.ghosts.push(ghost);
};
PacmanGame.prototype.moveGhost = function(ghost) {
var wrapPos = this.findWrapPos(ghost.x + ghost.v.x, ghost.y + ghost.v.y);
if (wrapPos) {
ghost.x = wrapPos.x;
ghost.y = wrapPos.y;
return;
}
var nextVs = this.availableDirections(ghost.x, ghost.y);
// protect against going backwards
var backwardsV = { x: ghost.v.x * -1, y: ghost.v.y * -1};
if (nextVs.length > 1) {
nextVs = nextVs
.filter(function(v) {
return v.x !== backwardsV.x || v.y !== backwardsV.y;
});
}
var nextV = Math.floor(Math.random() * (nextVs.length - 1));
ghost.v = nextVs[nextV];
ghost.x += ghost.v.x;
ghost.y += ghost.v.y;
};
PacmanGame.prototype.availableDirections = function(x, y) {
var res = [];
[{x: 0, y: 1}, {x : 0, y: -1}, { x: 1, y: 0 }, {x: -1, y: 0}]
.forEach(function(v) {
if (this.canMoveTo(x + v.x, y + v.y)) {
res.push(v);
}
}, this);
return res;
};
PacmanGame.prototype.canMoveTo = function(x, y) {
var tile = this.getPacmanTile(x, y);
return (tile === this.TilePoint ||
tile === this.TileBigP ||
tile === this.TileEmpty);
};
PacmanGame.prototype.findWrapPos = function(x, y) {
var wrapPos = this.wrapPos
.filter(function(p) {
return p.x === x && p.y === y;
});
if (wrapPos.length > 0) {
return wrapPos[0].wrapTo;
} else {
return null;
}
};
PacmanGame.prototype.checkPacmanEat = function() {
var p1Tile = this.getPacmanTile(this.p1.x, this.p1.y);
if (p1Tile === this.TilePoint) {
this.setPacmanTile(this.p1.x, this.p1.y, PacmanGame.PacmanTiles.EMPTY);
this.score++;
this.countPoints++;
if (this.countPoints === this.totalPoints) {
this.score += 100;
this.setGameOver();
}
} else if (p1Tile === this.TileBigP) {
this.setPacmanTile(this.p1.x, this.p1.y, PacmanGame.PacmanTiles.EMPTY);
this.score += 10;
}
};
PacmanGame.prototype.checkPacmanCaught = function() {
var game = this;
var p1 = this.p1;
this.ghosts.forEach(function(g) {
if (g.x === p1.x && g.y === p1.y) {
game.setGameOver();
}
});
};
PacmanGame.prototype.updateGhosts = function() {
this.ghosts.forEach(function(g) { this.moveGhost(g); }, this);
};
PacmanGame.prototype.tick = function() {
if (!this.gameOver) {
this.checkPacmanEat();
this.checkPacmanCaught();
}
this.putHud();
this.putTiles();
this.putMovables();
this.term.render();
};
PacmanGame.prototype.onKeyDown = function(k) {
var moveV = { x: 0, y: 0 };
switch (k) {
case ut.KEY_W:
moveV.y--;
break;
case ut.KEY_A:
moveV.x--;
break;
case ut.KEY_S:
moveV.y++;
break;
case ut.KEY_D:
moveV.x++;
break;
case ut.KEY_SPACE:
if (this.gameOver)
moveV = null;
break;
}
if (typeof this.onPacmanMove === 'function') {
this.onPacmanMove(moveV);
}
};
PacmanGame.prototype.start = function() {
this.gameOver = false;
this.generateMap();
this.term = new ut.Viewport(this.parent, 50, 30);
ut.initInput(this.onKeyDown.bind(this));
this.tick();
};
window.PacmanGame = PacmanGame;
}());
================================================
FILE: examples/pacman-unicode/readme.md
================================================
================================================
FILE: examples/pacman-unicode/unicodetiles/input.js
================================================
/// File: input.js
/// This file contains a very simple input system.
/*jshint browser:true */
/// Namespace: ut
/// Container namespace.
var ut = ut || {};
/// Constants: Keycodes
/// KEY_BACKSPACE - 8
/// KEY_TAB - 9
/// KEY_ENTER - 13
/// KEY_SHIFT - 16
/// KEY_CTRL - 17
/// KEY_ALT - 18
/// KEY_ESCAPE - 27
/// KEY_SPACE - 32
/// KEY_LEFT - 37
/// KEY_UP - 38
/// KEY_RIGHT - 39
/// KEY_DOWN - 40
/// KEY_0 - 48
/// KEY_1 - 49
/// KEY_2 - 50
/// KEY_3 - 51
/// KEY_4 - 52
/// KEY_5 - 53
/// KEY_6 - 54
/// KEY_7 - 55
/// KEY_8 - 56
/// KEY_9 - 57
/// KEY_A - 65
/// KEY_B - 66
/// KEY_C - 67
/// KEY_D - 68
/// KEY_E - 69
/// KEY_F - 70
/// KEY_G - 71
/// KEY_H - 72
/// KEY_I - 73
/// KEY_J - 74
/// KEY_K - 75
/// KEY_L - 76
/// KEY_M - 77
/// KEY_N - 78
/// KEY_O - 79
/// KEY_P - 80
/// KEY_Q - 81
/// KEY_R - 82
/// KEY_S - 83
/// KEY_T - 84
/// KEY_U - 85
/// KEY_V - 86
/// KEY_W - 87
/// KEY_X - 88
/// KEY_Y - 89
/// KEY_Z - 90
/// KEY_NUMPAD0 - 96
/// KEY_NUMPAD1 - 97
/// KEY_NUMPAD2 - 98
/// KEY_NUMPAD3 - 99
/// KEY_NUMPAD4 - 100
/// KEY_NUMPAD5 - 101
/// KEY_NUMPAD6 - 102
/// KEY_NUMPAD7 - 103
/// KEY_NUMPAD8 - 104
/// KEY_NUMPAD9 - 105
/// KEY_F1 - 112
/// KEY_F2 - 113
/// KEY_F3 - 114
/// KEY_F4 - 115
/// KEY_F5 - 116
/// KEY_F6 - 117
/// KEY_F7 - 118
/// KEY_F8 - 119
/// KEY_F9 - 120
/// KEY_F10 - 121
/// KEY_F11 - 122
/// KEY_F12 - 123
/// KEY_COMMA - 188
/// KEY_DASH - 189
/// KEY_PERIOD - 190
ut.KEY_BACKSPACE = 8;
ut.KEY_TAB = 9;
ut.KEY_ENTER = 13;
ut.KEY_SHIFT = 16;
ut.KEY_CTRL = 17;
ut.KEY_ALT = 18;
ut.KEY_ESCAPE = 27;
ut.KEY_SPACE = 32;
ut.KEY_LEFT = 37;
ut.KEY_UP = 38;
ut.KEY_RIGHT = 39;
ut.KEY_DOWN = 40;
ut.KEY_0 = 48;
ut.KEY_1 = 49;
ut.KEY_2 = 50;
ut.KEY_3 = 51;
ut.KEY_4 = 52;
ut.KEY_5 = 53;
ut.KEY_6 = 54;
ut.KEY_7 = 55;
ut.KEY_8 = 56;
ut.KEY_9 = 57;
ut.KEY_A = 65;
ut.KEY_B = 66;
ut.KEY_C = 67;
ut.KEY_D = 68;
ut.KEY_E = 69;
ut.KEY_F = 70;
ut.KEY_G = 71;
ut.KEY_H = 72;
ut.KEY_I = 73;
ut.KEY_J = 74;
ut.KEY_K = 75;
ut.KEY_L = 76;
ut.KEY_M = 77;
ut.KEY_N = 78;
ut.KEY_O = 79;
ut.KEY_P = 80;
ut.KEY_Q = 81;
ut.KEY_R = 82;
ut.KEY_S = 83;
ut.KEY_T = 84;
ut.KEY_U = 85;
ut.KEY_V = 86;
ut.KEY_W = 87;
ut.KEY_X = 88;
ut.KEY_Y = 89;
ut.KEY_Z = 90;
ut.KEY_NUMPAD0 = 96;
ut.KEY_NUMPAD1 = 97;
ut.KEY_NUMPAD2 = 98;
ut.KEY_NUMPAD3 = 99;
ut.KEY_NUMPAD4 = 100;
ut.KEY_NUMPAD5 = 101;
ut.KEY_NUMPAD6 = 102;
ut.KEY_NUMPAD7 = 103;
ut.KEY_NUMPAD8 = 104;
ut.KEY_NUMPAD9 = 105;
ut.KEY_F1 = 112;
ut.KEY_F2 = 113;
ut.KEY_F3 = 114;
ut.KEY_F4 = 115;
ut.KEY_F5 = 116;
ut.KEY_F6 = 117;
ut.KEY_F7 = 118;
ut.KEY_F8 = 119;
ut.KEY_F9 = 120;
ut.KEY_F10 = 121;
ut.KEY_F11 = 122;
ut.KEY_F12 = 123;
ut.KEY_COMMA = 188;
ut.KEY_DASH = 189;
ut.KEY_PERIOD = 190;
ut.pressedKeys = {};
ut.keyRepeatDelay = 150;
/// Function: isKeyPressed
/// Checks if given key is pressed down. You must call first.
///
/// Parameters:
/// key - key code to check
///
/// Returns:
/// True if the key is pressed down, false otherwise.
ut.isKeyPressed = function(key) {
"use strict";
if (ut.pressedKeys[key]) return true;
else return false;
};
/// Function: setKeyRepeatInterval
/// Sets the interval when user's onKeyDown handler is called when a key is held down.
/// must be called with a handler for this to work.
///
/// Parameters:
/// milliseconds - the interval delay in milliseconds (1 second = 1000 milliseconds)
ut.setKeyRepeatInterval = function(milliseconds) {
"use strict";
ut.keyRepeatDelay = milliseconds;
};
/// Function: initInput
/// Initilizes input by assigning default key handlers and optional user's handlers.
/// This must be called in order to to work.
///
/// Parameters:
/// onkeydown - (optional) function(keyCode) for key down event handler
/// onkeyup - (optional) function(keyCode) for key up event handler
ut.initInput = function(onKeyDown, onKeyUp) {
ut.onkeydown = onKeyDown;
ut.onkeyup = onKeyUp;
// Attach default onkeydown handler that updates pressedKeys
document.onkeydown = function(event) {
"use strict";
var k = event.keyCode;
if (ut.pressedKeys[k] !== null && ut.pressedKeys[k] !== undefined) return false;
ut.pressedKeys[k] = true;
if (ut.onkeydown) {
ut.onkeydown(k); // User event handler
// Setup keyrepeat
ut.pressedKeys[k] = setInterval("ut.onkeydown("+k+")", ut.keyRepeatDelay);
}
if (ut.pressedKeys[ut.KEY_CTRL] || ut.pressedKeys[ut.KEY_ALT])
return true; // CTRL/ALT for browser hotkeys
else return false;
};
// Attach default onkeyup handler that updates pressedKeys
document.onkeyup = function(event) {
"use strict";
var k = event.keyCode;
if (ut.onkeydown && ut.pressedKeys[k] !== null && ut.pressedKeys[k] !== undefined)
clearInterval(ut.pressedKeys[k]);
ut.pressedKeys[k] = null;
if (ut.onkeyup) ut.onkeyup(k); // User event handler
return false;
};
// Avoid keys getting stuck at down
window.onblur = function() {
"use strict";
for (var k in ut.pressedKeys)
if (ut.onkeydown && ut.pressedKeys[k] !== null)
clearInterval(ut.pressedKeys[k]);
ut.pressedKeys = {};
};
};
================================================
FILE: examples/pacman-unicode/unicodetiles/unicodetiles.css
================================================
@charset "utf-8";
@font-face {
font-family: 'DejaVuSansMono';
src: url('DejaVuSansMono.eot');
src: url('DejaVuSansMono.eot?#iefix') format('eot'),
url('DejaVuSansMono.woff') format('woff'),
url('DejaVuSansMono.ttf') format('truetype');
}
.unicodetiles {
font-family: "DejaVuSansMono", "DejaVu Sans Mono", monospace;
white-space: pre;
text-align: center;
line-height: 1;
letter-spacing: 0px;
display: inline-block;
}
.unicodetiles div {
float: left;
height: 1em;
}
.unicodetiles br {
clear: both;
}
================================================
FILE: examples/pacman-unicode/unicodetiles/unicodetiles.js
================================================
/// File: unicodetiles.js
/// This file contains the main tile engine namespace.
/// All coordinates are assumed to be integers - behaviour is undefined
/// if you feed in floats (or anything other) as x and y (or similar) parameters.
/*jshint browser:true devel:true trailing:true latedef:true undef:true unused:true newcap:true */
if (!window.console) {
window.console = { log: function(){}, warn: function(){}, error: function(){} }
}
/// Namespace: ut
/// Container namespace.
var ut = ut || {};
/// Constants: Semi-internal constants for ut namespace
/// VERSION - Version of the library as string.
/// NULLCHAR - Character used when none is specified otherwise.
/// CSSCLASS - The CSS class name used for the tile engine element.
/// NULLTILE - The tile used as placeholder for empty tile.
ut.VERSION = "2.1";
ut.NULLCHAR = " ";
ut.CSSCLASS = "unicodetiles";
ut.NULLTILE = {}; // Initialized properly after ut.Tile is defined
/// Class: Tile
/// Represents a unicode character tile with various attributes.
/// Constructor: Tile
/// Constructs a new Tile object.
///
/// Parameters:
/// ch - a character to display for this tile
/// r - (optional) red foregorund color component 0-255
/// g - (optional) green foreground color component 0-255
/// b - (optional) blue foreground color component 0-255
/// br - (optional) red background color component 0-255
/// bg - (optional) green background color component 0-255
/// bb - (optional) blue background color component 0-255
ut.Tile = function(ch, r, g, b, br, bg, bb) {
"use strict";
this.ch = ch || ut.NULLCHAR;
this.r = r;
this.g = g;
this.b = b;
this.br = br;
this.bg = bg;
this.bb = bb;
};
/// Function: getChar
/// Returns the character of this tile.
ut.Tile.prototype.getChar = function() { return this.ch; };
/// Function: setChar
/// Sets the character of this tile.
ut.Tile.prototype.setChar = function(ch) { this.ch = ch; };
/// Function: setColor
/// Sets the foreground color of this tile.
ut.Tile.prototype.setColor = function(r, g, b) { this.r = r; this.g = g; this.b = b; };
/// Function: setGrey
/// Sets the foreground color to the given shade (0-255) of grey.
ut.Tile.prototype.setGrey = function(grey) { this.r = grey; this.g = grey; this.b = grey; };
/// Function: setBackground
/// Sets the background color of this tile.
ut.Tile.prototype.setBackground = function(r, g, b) { this.br = r; this.bg = g; this.bb = b; };
/// Function: resetColor
/// Clears the color of this tile / assigns default color.
ut.Tile.prototype.resetColor = function() { this.r = this.g = this.b = undefined; };
/// Function: resetBackground
/// Clears the background color of this tile.
ut.Tile.prototype.resetBackground = function() { this.br = this.bg = this.bb = undefined; };
/// Function: getColorHex
/// Returns the hexadecimal representation of the color
ut.Tile.prototype.getColorHex = function() {
if (this.r !== undefined && this.g !== undefined && this.b !== undefined)
return "#" + this.r.toString(16) + this.g.toString(16) + this.b.toString(16);
else return "";
};
/// Function: getBackgroundHex
/// Returns the hexadecimal representation of the background color
ut.Tile.prototype.getBackgroundHex = function() {
if (this.br !== undefined && this.bg !== undefined && this.bb !== undefined)
return "#" + this.br.toString(16) + this.bg.toString(16) + this.bb.toString(16);
else return "";
};
/// Function: getColorRGB
/// Returns the CSS rgb(r,g,b) representation of the color
ut.Tile.prototype.getColorRGB = function() {
if (this.r !== undefined && this.g !== undefined && this.b !== undefined)
return 'rgb('+this.r+','+this.g+','+this.b+')';
else return "";
};
/// Function: getBackgroundRGB
/// Returns the CSS rgb(r,g,b) representation of the background color
ut.Tile.prototype.getBackgroundRGB = function() {
if (this.br !== undefined && this.bg !== undefined && this.bb !== undefined)
return 'rgb('+this.br+','+this.bg+','+this.bb+')';
else return "";
};
/// Function: getColorJSON
/// Returns the JSON representation of the color, i.e. object { r, g, b }
ut.Tile.prototype.getColorJSON = function() {
if (this.r !== undefined && this.g !== undefined && this.b !== undefined)
return { "r": this.r, "g": this.g, "b": this.b };
else return {};
};
/// Function: getBackgroundJSON
/// Returns the JSON representation of the background color, i.e. object { r, g, b }
ut.Tile.prototype.getBackgroundJSON = function() {
if (this.r !== undefined && this.g !== undefined && this.b !== undefined)
return { "r": this.br, "g": this.bg, "b": this.bb };
else return {};
};
/// Function: copy
/// Makes this tile identical to the one supplied. Custom properties are not copied.
ut.Tile.prototype.copy = function(other) {
this.ch = other.ch;
this.r = other.r; this.g = other.g; this.b = other.b;
this.br = other.br; this.bg = other.bg; this.bb = other.bb;
};
/// Function: clone
/// Returns a new copy of this tile. Custom properties are not cloned.
ut.Tile.prototype.clone = function() {
return new ut.Tile(this.ch, this.r, this.g, this.b, this.br, this.bg, this.bb);
};
ut.NULLTILE = new ut.Tile();
/// Class: Viewport
/// The tile engine viewport / window. Takes care of initializing a proper renderer.
/// Constructor: Viewport
/// Constructs a new Viewport object.
/// If you wish to display a player character at the center, you should use odd sizes.
///
/// Parameters:
/// elem - the DOM element which shall be transformed into the tile engine
/// w - (integer) width in tiles
/// h - (integer) height in tiles
/// renderer - (optional) choose rendering engine, see , defaults to "auto".
/// squarify - (optional) set to true to force the tiles square; may break some box drawing
ut.Viewport = function(elem, w, h, renderer, squarify) {
"use strict";
this.elem = elem;
this.elem.innerHTML = "";
this.w = w;
this.h = h;
this.renderer = null; // setRenderer() is called later
this.squarify = squarify;
this.cx = Math.floor(w/2);
this.cy = Math.floor(h/2);
// Add CSS class if not added already
if (elem.className.indexOf(ut.CSSCLASS) === -1) {
if (elem.className.length === 0) elem.className = ut.CSSCLASS;
else elem.className += " " + ut.CSSCLASS;
}
// Create two 2-dimensional array to hold the viewport tiles
this.buffer = new Array(h);
for (var j = 0; j < h; ++j) {
this.buffer[j] = new Array(w);
for (var i = 0; i < w; ++i) {
this.buffer[j][i] = new ut.Tile();
}
}
/// Function: updateStyle
/// If the style of the parent element is modified, this needs to be called.
this.updateStyle = function(updateRenderer) {
var s = window.getComputedStyle(this.elem, null);
this.defaultColor = s.color;
this.defaultBackground = s.backgroundColor;
if (updateRenderer !== false)
this.renderer.updateStyle(s);
};
/// Function: setRenderer
/// Switch renderer at runtime. All methods fallback to "dom" if unsuccesful.
/// Possible values:
/// * "webgl" - Use WebGL with an HTML5 element
/// * "canvas" - Use HTML5 element
/// * "dom" - Use regular HTML element manipulation through DOM
/// * "auto" - Use best available, i.e. try the above in order, picking the first that works
this.setRenderer = function(newrenderer) {
this.elem.innerHTML = "";
if (newrenderer === "auto" || newrenderer === "webgl") {
try {
this.renderer = new ut.WebGLRenderer(this);
} catch (e) {
console.error(e);
newrenderer = "canvas";
this.elem.innerHTML = "";
}
}
if (newrenderer === "canvas") {
try {
this.renderer = new ut.CanvasRenderer(this);
} catch (e) {
console.error(e);
newrenderer = "dom";
this.elem.innerHTML = "";
}
}
if (newrenderer === "dom") {
this.renderer = new ut.DOMRenderer(this);
}
this.updateStyle(false);
};
this.setRenderer(renderer || "auto");
};
/// Function: getRendererString
/// Gets the currently used renderer.
///
/// Returns:
/// One of "webgl", "canvas", "dom", "".
ut.Viewport.prototype.getRendererString = function() {
if (this.renderer instanceof ut.WebGLRenderer) return "webgl";
if (this.renderer instanceof ut.CanvasRenderer) return "canvas";
if (this.renderer instanceof ut.DOMRenderer) return "dom";
return "";
};
/// Function: put
/// Puts a tile to the given coordinates.
/// Checks bounds and does nothing if invalid coordinates are given.
///
/// Parameters:
/// tile - the tile to put
/// x - (integer) x coordinate
/// y - (integer) y coordinate
ut.Viewport.prototype.put = function(tile, x, y) {
if (x < 0 || y < 0 || x >= this.w || y >= this.h) return;
this.buffer[y][x] = tile;
};
/// Function: unsafePut
/// Puts a tile to the given coordinates.
/// Does *not* check bounds; throws exception if invalid coordinates are given.
///
/// Parameters:
/// tile - the tile to put
/// x - (integer) x coordinate
/// y - (integer) y coordinate
ut.Viewport.prototype.unsafePut = function(tile, x, y) {
this.buffer[y][x] = tile;
};
/// Function: putString
/// Creates a row of tiles with the chars of the given string.
/// Wraps to next line if it can't fit the chars on one line.
///
/// Parameters:
/// str - (string) the string to put
/// x - (integer) x coordinate (column)
/// y - (integer) y coordinate (row)
/// r - (optional) red foregorund color component 0-255
/// g - (optional) green foreground color component 0-255
/// b - (optional) blue foreground color component 0-255
/// br - (optional) red background color component 0-255
/// bg - (optional) green background color component 0-255
/// bb - (optional) blue background color component 0-255
ut.Viewport.prototype.putString = function(str, x, y, r, g, b, br, bg, bb) {
var len = str.length;
var tile;
if (x < 0 || y < 0) return;
for (var i = 0; i < len; ++i) {
if (x >= this.w) { x = 0; ++y;}
if (y >= this.h) return;
tile = new ut.Tile(str[i], r, g, b, br, bg, bb);
this.unsafePut(tile, x, y);
++x;
}
};
/// Function: get
/// Returns the tile in the given coordinates.
/// Checks bounds and returns empty tile if invalid coordinates are given.
///
/// Parameters:
/// x - (integer) x coordinate
/// y - (integer) y coordinate
///
/// Returns:
/// The tile.
ut.Viewport.prototype.get = function(x, y) {
if (x < 0 || y < 0 || x >= this.w || y >= this.h) return ut.NULLTILE;
return this.buffer[y][x];
};
/// Function: clear
/// Clears the viewport buffer by assigning empty tiles.
ut.Viewport.prototype.clear = function() {
for (var j = 0; j < this.h; ++j) {
for (var i = 0; i < this.w; ++i) {
this.buffer[j][i] = ut.NULLTILE;
}
}
this.renderer.clear();
};
/// Function: render
/// Renders the buffer as html to the element specified at construction.
ut.Viewport.prototype.render = function() {
this.renderer.render();
};
/// Class: Engine
/// The tile engine itself.
/// Constructor: Engine
/// Constructs a new Engine object. If width or height is given,
/// it will not attempt to fetch tiles outside the boundaries.
/// In that case 0,0 is assumed as the upper-left corner of the world,
/// but if no width/height is given also negative coords are valid.
///
/// Parameters:
/// vp - the instance to use as the viewport
/// func - the function used for fetching tiles
/// w - (integer) (optional) world width in tiles
/// h - (integer) (optional) world height in tiles
ut.Engine = function(vp, func, w, h) {
"use strict";
this.viewport = vp;
this.tileFunc = func;
this.w = w;
this.h = h;
this.refreshCache = true;
this.cacheEnabled = false;
this.transitionTimer = null;
this.transitionDuration = 0;
this.transition = null;
this.cachex = 0;
this.cachey = 0;
this.tileCache = new Array(vp.h);
this.tileCache2 = new Array(vp.h);
for (var j = 0; j < vp.h; ++j) {
this.tileCache[j] = new Array(vp.w);
this.tileCache2[j] = new Array(vp.w);
}
};
/// Function: setTileFunc
/// Sets the function to be called with coordinates to fetch each tile.
/// Optionally can apply a transition effect. Effects are:
/// "boxin", "boxout", "circlein", "circleout", "random"
///
/// Parameters:
/// func - function taking parameters (x, y) and returning an ut.Tile
/// effect - (string) (optional) name of effect to use (see above for legal values)
/// duration - (integer) (optional) how many milliseconds the transition effect should last
ut.Engine.prototype.setTileFunc = function(func, effect, duration) {
"use strict";
if (effect) {
this.transition = undefined;
if (typeof effect === "string") {
if (effect === "boxin") this.transition = function(x, y, w, h, new_t, old_t, factor) {
var halfw = w * 0.5, halfh = h * 0.5;
x -= halfw; y -= halfh;
if (Math.abs(x) < halfw * factor && Math.abs(y) < halfh * factor) return new_t;
else return old_t;
};
else if (effect === "boxout") this.transition = function(x, y, w, h, new_t, old_t, factor) {
var halfw = w * 0.5, halfh = h * 0.5;
x -= halfw; y -= halfh;
factor = 1.0 - factor;
if (Math.abs(x) < halfw * factor && Math.abs(y) < halfh * factor) return old_t;
else return new_t;
};
else if (effect === "circlein") this.transition = function(x, y, w, h, new_t, old_t, factor) {
var halfw = w * 0.5, halfh = h * 0.5;
x -= halfw; y -= halfh;
if (x*x + y*y < (halfw*halfw + halfh*halfh) * factor) return new_t;
else return old_t;
};
else if (effect === "circleout") this.transition = function(x, y, w, h, new_t, old_t, factor) {
var halfw = w * 0.5, halfh = h * 0.5;
x -= halfw; y -= halfh;
factor = 1.0 - factor;
if (x*x + y*y > (halfw*halfw + halfh*halfh) * factor) return new_t;
else return old_t;
};
else if (effect === "random") this.transition = function(x, y, w, h, new_t, old_t, factor) {
if (Math.random() > factor) return old_t;
else return new_t;
};
}
if (this.transition) {
this.transitionTimer = (new Date()).getTime();
this.transitionDuration = duration || 500;
}
}
this.tileFunc = func;
};
/// Function: setMaskFunc
/// Sets the function to be called to fetch mask information according to coordinates.
/// If mask function returns false to some coordinates, then that tile is not rendered.
///
/// Parameters:
/// func - function taking parameters (x, y) and returning a true if the tile is visible
ut.Engine.prototype.setMaskFunc = function(func) { this.maskFunc = func; };
/// Function: setShaderFunc
/// Sets the function to be called to post-process / shade each visible tile.
/// Shader function is called even if caching is enabled, see .
///
/// Parameters:
/// func - function taking parameters (tile, x, y) and returning an ut.Tile
ut.Engine.prototype.setShaderFunc = function(func) { this.shaderFunc = func; };
/// Function: setWorldSize
/// Tiles outside of the range x = [0,width[; y = [0,height[ are not fetched.
/// Set to undefined in order to make the world infinite.
///
/// Parameters:
/// width - (integer) new world width
/// height - (integer) new world height
ut.Engine.prototype.setWorldSize = function(width, height) { this.w = width; this.h = height; };
/// Function: setCacheEnabled
/// Enables or disables the usage of tile cache. This means that
/// extra measures are taken to not call the tile function unnecessarily.
/// This means that all animating must be done in a shader function,
/// see .
/// Cache is off by default, but should be enabled if the tile function
/// does more computation than a simple array look-up.
///
/// Parameters:
/// mode - true to enable, false to disable
ut.Engine.prototype.setCacheEnabled = function(mode) { this.cacheEnabled = mode; this.refreshCache = true; };
/// Function: update
/// Updates the viewport according to the given player coordinates.
/// The algorithm goes as follows:
/// * Record the current time
/// * For each viewport tile:
/// * Check if the tile is visible by testing the mask
/// * If not visible, continue to the next tile in the viewport
/// * Otherwise, if cache is enabled try to fetch the tile from there
/// * Otherwise, call the tile function and check for shader function presence
/// * If there is shader function, apply it to the tile, passing the recorded time
/// * Put the tile to viewport
///
/// Parameters:
/// x - (integer) viewport center x coordinate in the tile world
/// y - (integer) viewport center y coordinate in the tile world
ut.Engine.prototype.update = function(x, y) {
"use strict";
x = x || 0;
y = y || 0;
// World coords of upper left corner of the viewport
var xx = x - this.viewport.cx;
var yy = y - this.viewport.cy;
var timeNow = (new Date()).getTime(); // For passing to shaderFunc
var transTime;
if (this.transition) transTime = (timeNow - this.transitionTimer) / this.transitionDuration;
if (transTime >= 1.0) this.transition = undefined;
var tile;
// For each tile in viewport...
for (var j = 0; j < this.viewport.h; ++j) {
for (var i = 0; i < this.viewport.w; ++i) {
var ixx = i+xx, jyy = j+yy;
// Check horizontal bounds if requested
if (this.w && (ixx < 0 || ixx >= this.w)) {
tile = ut.NULLTILE;
// Check vertical bounds if requested
} else if (this.h && (jyy < 0 || jyy >= this.w)) {
tile = ut.NULLTILE;
// Check mask
} else if (this.maskFunc && !this.maskFunc(ixx, jyy)) {
tile = ut.NULLTILE;
// Check transition effect
} else if (this.transition && !this.refreshCache) {
tile = this.transition(i, j, this.viewport.w, this.viewport.h,
this.tileFunc(ixx, jyy), this.tileCache[j][i], transTime);
// Check cache
} else if (this.cacheEnabled && !this.refreshCache) {
var lookupx = ixx - this.cachex;
var lookupy = jyy - this.cachey;
if (lookupx >= 0 && lookupx < this.viewport.w && lookupy >= 0 && lookupy < this.viewport.h) {
tile = this.tileCache[lookupy][lookupx];
if (tile === ut.NULLTILE) tile = this.tileFunc(ixx, jyy);
} else // Cache miss
tile = this.tileFunc(ixx, jyy);
// If all else fails, call tileFunc
} else tile = this.tileFunc(ixx, jyy);
// Save the tile to cache (always due to transition effects)
this.tileCache2[j][i] = tile;
// Apply shader function
if (this.shaderFunc && tile !== ut.NULLTILE)
tile = this.shaderFunc(tile, ixx, jyy, timeNow);
// Put shaded tile to viewport
this.viewport.unsafePut(tile, i, j);
}
}
// Cache stuff is enabled always, because it is also required by transitions
// Save the new cache origin
this.cachex = xx;
this.cachey = yy;
// Swap cache buffers
var tempCache = this.tileCache;
this.tileCache = this.tileCache2;
this.tileCache2 = tempCache;
this.refreshCache = false;
};
================================================
FILE: examples/pacman-unicode/unicodetiles/ut.CanvasRenderer.js
================================================
/*global ut */
/// Class: CanvasRenderer
/// Renders the into an HTML5 element.
///
/// *Note:* This is an internal class used by
ut.CanvasRenderer = function(view) {
"use strict";
this.view = view;
this.canvas = document.createElement("canvas");
if (!this.canvas.getContext) throw("Canvas not supported");
this.ctx2 = this.canvas.getContext("2d");
if (!this.ctx2 || !this.ctx2.fillText) throw("Canvas not supported");
view.elem.appendChild(this.canvas);
// Create an offscreen canvas for rendering
this.offscreen = document.createElement("canvas");
this.ctx = this.offscreen.getContext("2d");
this.updateStyle();
this.canvas.width = (view.squarify ? this.th : this.tw) * view.w;
this.canvas.height = this.th * view.h;
this.offscreen.width = this.canvas.width;
this.offscreen.height = this.canvas.height;
// Doing this again since setting canvas w/h resets the state
this.updateStyle();
};
ut.CanvasRenderer.prototype.updateStyle = function(s) {
"use strict";
s = s || window.getComputedStyle(this.view.elem, null);
this.ctx.font = s.fontSize + "/" + s.lineHeight + " " + s.fontFamily;
this.ctx.textBaseline = "middle";
this.tw = this.ctx.measureText("M").width;
this.th = parseInt(s.fontSize, 10);
this.gap = this.view.squarify ? (this.th - this.tw) : 0;
if (this.view.squarify) this.tw = this.th;
};
ut.CanvasRenderer.prototype.clear = function() { /* No op */ };
ut.CanvasRenderer.prototype.render = function() {
"use strict";
var tile, ch, fg, bg, x, y;
var view = this.view, buffer = this.view.buffer;
var w = view.w, h = view.h;
var hth = 0.5 * this.th;
var hgap = 0.5 * this.gap; // Squarification
// Clearing with one big rect is much faster than with individual char rects
this.ctx.fillStyle = view.defaultBackground;
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
y = hth; // half because textBaseline is middle
for (var j = 0; j < h; ++j) {
x = 0;
for (var i = 0; i < w; ++i) {
tile = buffer[j][i];
ch = tile.ch;
fg = tile.getColorRGB();
bg = tile.getBackgroundRGB();
// Only render background if the color is non-default
if (bg.length && bg !== view.defaultBackground) {
this.ctx.fillStyle = bg;
this.ctx.fillRect(x, y-hth, this.tw, this.th);
}
// Do not attempt to render empty char
if (ch.length) {
if (!fg.length) fg = view.defaultColor;
this.ctx.fillStyle = fg;
this.ctx.fillText(ch, x+hgap, y);
}
x += this.tw;
}
y += this.th;
}
this.ctx2.drawImage(this.offscreen, 0, 0);
};
================================================
FILE: examples/pacman-unicode/unicodetiles/ut.DOMRenderer.js
================================================
/*global ut */
/// Class: DOMRenderer
/// Renders the into DOM elements.
///
/// *Note:* This is an internal class used by
ut.DOMRenderer = function(view) {
"use strict";
this.view = view;
// Create a matrix of elements, cache references
this.spans = new Array(view.h);
this.colors = new Array(view.h);
for (var j = 0; j < view.h; ++j) {
this.spans[j] = new Array(view.w);
this.colors[j] = new Array(view.w);
for (var i = 0; i < view.w; ++i) {
this.spans[j][i] = document.createElement("div");
view.elem.appendChild(this.spans[j][i]);
}
// Line break
this.spans[j].push(document.createElement("br"));
view.elem.appendChild(this.spans[j][view.w]);
}
ut.viewportStyleUpdaterHack = this;
setTimeout(function() { ut.viewportStyleUpdaterHack.updateStyle(); }, 0);
};
ut.DOMRenderer.prototype.updateStyle = function(s) {
"use strict";
s = window.getComputedStyle(this.spans[0][0], null);
this.tw = parseInt(s.width, 10);
if (this.tw === 0 || isNaN(this.tw)) return; // Nothing to do, exit
this.th = parseInt(s.height, 10);
if (this.view.squarify) this.tw = this.th;
var w = this.view.w, h = this.view.h;
for (var j = 0; j < h; ++j) {
for (var i = 0; i < w; ++i) {
this.spans[j][i].style.width = this.tw + "px";
}
}
};
ut.DOMRenderer.prototype.clear = function() {
"use strict";
for (var j = 0; j < this.view.h; ++j) {
for (var i = 0; i < this.view.w; ++i) {
this.colors[j][i] = "";
}
}
};
ut.DOMRenderer.prototype.render = function() {
"use strict";
var w = this.view.w, h = this.view.h;
var buffer = this.view.buffer;
var defaultColor = this.view.defaultColor;
var defaultBackground = this.view.defaultBackground;
for (var j = 0; j < h; ++j) {
for (var i = 0; i < w; ++i) {
var tile = buffer[j][i];
var span = this.spans[j][i];
// Check and update colors
var fg = tile.r === undefined ? defaultColor : tile.getColorRGB();
var bg = tile.br === undefined ? defaultBackground : tile.getBackgroundRGB();
var colorHash = fg + bg;
if (colorHash !== this.colors[j][i]) {
this.colors[j][i] = colorHash;
span.style.color = fg;
span.style.backgroundColor = bg;
}
// Check and update character
var ch = tile.getChar();
if (ch !== span.innerHTML)
span.innerHTML = ch;
}
}
};
ut.viewportStyleUpdaterHack = null;
================================================
FILE: examples/pacman-unicode/unicodetiles/ut.WebGLRenderer.js
================================================
/*global ut */
/// Class: WebGLRenderer
/// Renders the with WebGL.
/// Given decent GPU drivers and browser support, this is the fastest renderer.
///
/// *Note:* This is an internal class used by
ut.WebGLRenderer = function(view) {
"use strict";
this.view = view;
this.canvas = document.createElement("canvas");
// Try to fetch the context
if (!this.canvas.getContext) throw("Canvas not supported");
this.gl = this.canvas.getContext("experimental-webgl");
if (!this.gl) throw("WebGL not supported");
var gl = this.gl;
view.elem.appendChild(this.canvas);
this.charMap = {};
this.charArray = [];
this.defaultColors = { r: 1.0, g: 1.0, b: 1.0, br: 0.0, bg: 0.0, bb: 0.0 };
this.attribs = {
position: { buffer: null, data: null, itemSize: 2, location: null, hint: gl.STATIC_DRAW },
texCoord: { buffer: null, data: null, itemSize: 2, location: null, hint: gl.STATIC_DRAW },
color: { buffer: null, data: null, itemSize: 3, location: null, hint: gl.DYNAMIC_DRAW },
bgColor: { buffer: null, data: null, itemSize: 3, location: null, hint: gl.DYNAMIC_DRAW },
charIndex: { buffer: null, data: null, itemSize: 1, location: null, hint: gl.DYNAMIC_DRAW }
};
function insertQuad(arr, i, x, y, w, h) {
var x1 = x, y1 = y, x2 = x + w, y2 = y + h;
arr[ i] = x1; arr[++i] = y1;
arr[++i] = x2; arr[++i] = y1;
arr[++i] = x1; arr[++i] = y2;
arr[++i] = x1; arr[++i] = y2;
arr[++i] = x2; arr[++i] = y1;
arr[++i] = x2; arr[++i] = y2;
}
this.initBuffers = function() {
var a, attrib, attribs = this.attribs;
var w = this.view.w, h = this.view.h;
// Allocate data arrays
for (a in this.attribs) {
attrib = attribs[a];
attrib.data = new Float32Array(attrib.itemSize * 6 * w * h);
}
// Generate static data
for (var j = 0; j < h; ++j) {
for (var i = 0; i < w; ++i) {
// Position & texCoords
var k = attribs.position.itemSize * 6 * (j * w + i);
insertQuad(attribs.position.data, k, i * this.tw, j * this.th, this.tw, this.th);
insertQuad(attribs.texCoord.data, k, 0.0, 0.0, 1.0, 1.0);
}
}
// Upload
for (a in this.attribs) {
attrib = attribs[a];
if (attrib.buffer) gl.deleteBuffer(attrib.buffer);
attrib.buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, attrib.buffer);
gl.bufferData(gl.ARRAY_BUFFER, attrib.data, attrib.hint);
gl.enableVertexAttribArray(attrib.location);
gl.vertexAttribPointer(attrib.location, attrib.itemSize, gl.FLOAT, false, 0, 0);
}
};
// Create an offscreen canvas for rendering text to texture
if (!this.offscreen)
this.offscreen = document.createElement("canvas");
this.offscreen.style.position = "absolute";
this.offscreen.style.top = "0px";
this.offscreen.style.left = "0px";
this.ctx = this.offscreen.getContext("2d");
if (!this.ctx) throw "Failed to acquire offscreen canvas drawing context";
// WebGL drawing canvas
this.updateStyle();
this.canvas.width = (view.squarify ? this.th : this.tw) * view.w;
this.canvas.height = this.th * view.h;
this.offscreen.width = 0;
this.offscreen.height = 0;
// Doing this again since setting canvas w/h resets the state
this.updateStyle();
gl.viewport(0, 0, this.canvas.width, this.canvas.height);
// Setup GLSL
function compileShader(type, source) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
var ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!ok) {
var msg = "Error compiling shader: " + gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw msg;
}
return shader;
}
var vertexShader = compileShader(gl.VERTEX_SHADER, ut.WebGLRenderer.VERTEX_SHADER);
var fragmentShader = compileShader(gl.FRAGMENT_SHADER, ut.WebGLRenderer.FRAGMENT_SHADER);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
var ok = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!ok) {
var msg = "Error linking program: " + gl.getProgramInfoLog(program);
gl.deleteProgram(program);
throw msg;
}
gl.useProgram(program);
// Get attribute locations
this.attribs.position.location = gl.getAttribLocation(program, "position");
this.attribs.texCoord.location = gl.getAttribLocation(program, "texCoord");
this.attribs.color.location = gl.getAttribLocation(program, "color");
this.attribs.bgColor.location = gl.getAttribLocation(program, "bgColor");
this.attribs.charIndex.location = gl.getAttribLocation(program, "charIndex");
// Setup buffers and uniforms
this.initBuffers();
var resolutionLocation = gl.getUniformLocation(program, "uResolution");
gl.uniform2f(resolutionLocation, this.canvas.width, this.canvas.height);
this.tileCountsLocation = gl.getUniformLocation(program, "uTileCounts");
gl.uniform2f(this.tileCountsLocation, this.view.w, this.view.h);
this.paddingLocation = gl.getUniformLocation(program, "uPadding");
gl.uniform2f(this.paddingLocation, 0.0, 0.0);
// Setup texture
//view.elem.appendChild(this.offscreen); // Debug offscreen
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
this.cacheChars(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.activeTexture(gl.TEXTURE0);
var _this = this;
setTimeout(function() { _this.updateStyle(); _this.buildTexture(); _this.render(); }, 100);
};
/////////////////
// Build texture
ut.WebGLRenderer.prototype.buildTexture = function() {
"use strict";
var gl = this.gl;
var w = this.offscreen.width / (this.tw + this.pad), h = this.offscreen.height / (this.th + this.pad);
// Check if need to resize the canvas
var charCount = this.charArray.length;
if (charCount > Math.floor(w) * Math.floor(h)) {
w = Math.ceil(Math.sqrt(charCount));
h = w + 2; // Allocate some extra space too
this.offscreen.width = w * (this.tw + this.pad);
this.offscreen.height = h * (this.th + this.pad);
this.updateStyle();
gl.uniform2f(this.tileCountsLocation, w, h);
}
gl.uniform2f(this.paddingLocation, this.pad / this.offscreen.width, this.pad / this.offscreen.height);
var c = 0, ch;
var halfGap = 0.5 * this.gap; // Squarification
this.ctx.fillStyle = "#000000";
this.ctx.fillRect(0, 0, this.offscreen.width, this.offscreen.height);
this.ctx.fillStyle = "#ffffff";
var tw = this.tw + this.pad;
var th = this.th + this.pad;
var y = 0.5 * th; // Half because textBaseline is middle
for (var j = 0; j < h; ++j) {
var x = this.pad * 0.5;
for (var i = 0; i < w; ++i, ++c) {
ch = this.charArray[c];
if (ch === undefined) break;
this.ctx.fillText(ch, x + halfGap, y);
x += tw;
}
if (!ch) break;
y += th;
}
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.offscreen);
};
///////////////
// Cache chars
ut.WebGLRenderer.prototype.cacheChars = function(chars, build) {
"use strict";
if (!this.gl) return; // Nothing to do if not using WebGL renderer
var changed = false;
for (var i = 0; i < chars.length; ++i) {
if (!this.charMap[chars[i]]) {
changed = true;
this.charArray.push(chars[i]);
this.charMap[chars[i]] = this.charArray.length-1;
}
}
if (changed && build !== false) this.buildTexture();
};
////////////////
// Update style
ut.WebGLRenderer.prototype.updateStyle = function(s) {
"use strict";
s = s || window.getComputedStyle(this.view.elem, null);
this.ctx.font = s.fontSize + "/" + s.lineHeight + " " + s.fontFamily;
this.ctx.textBaseline = "middle";
this.ctx.fillStyle = "#ffffff";
this.tw = this.ctx.measureText("M").width;
this.th = parseInt(s.fontSize, 10);
this.gap = this.view.squarify ? (this.th - this.tw) : 0;
if (this.view.squarify) this.tw = this.th;
this.pad = Math.ceil(this.th * 0.2) * 2.0; // Must be even number
var color = s.color.match(/\d+/g);
var bgColor = s.backgroundColor.match(/\d+/g);
this.defaultColors.r = parseInt(color[0], 10) / 255;
this.defaultColors.g = parseInt(color[1], 10) / 255;
this.defaultColors.b = parseInt(color[2], 10) / 255;
this.defaultColors.br = parseInt(bgColor[0], 10) / 255;
this.defaultColors.bg = parseInt(bgColor[1], 10) / 255;
this.defaultColors.bb = parseInt(bgColor[2], 10) / 255;
};
ut.WebGLRenderer.prototype.clear = function() { /* No op */ };
//////////
// Render
ut.WebGLRenderer.prototype.render = function() {
"use strict";
var gl = this.gl;
gl.clear(gl.COLOR_BUFFER_BIT);
var attribs = this.attribs;
var w = this.view.w, h = this.view.h;
// Create new tile data
var tiles = this.view.buffer;
var defaultColor = this.view.defaultColor;
var defaultBgColor = this.view.defaultBackground;
var newChars = false;
for (var j = 0; j < h; ++j) {
for (var i = 0; i < w; ++i) {
var tile = tiles[j][i];
var ch = this.charMap[tile.ch];
if (ch === undefined) { // Auto-cache new characters
this.cacheChars(tile.ch, false);
newChars = true;
ch = this.charMap[tile.ch];
}
var k = attribs.color.itemSize * 6 * (j * w + i);
var kk = attribs.charIndex.itemSize * 6 * (j * w + i);
var r = tile.r === undefined ? this.defaultColors.r : tile.r / 255;
var g = tile.g === undefined ? this.defaultColors.g : tile.g / 255;
var b = tile.b === undefined ? this.defaultColors.b : tile.b / 255;
var br = tile.br === undefined ? this.defaultColors.br : tile.br / 255;
var bg = tile.bg === undefined ? this.defaultColors.bg : tile.bg / 255;
var bb = tile.bb === undefined ? this.defaultColors.bb : tile.bb / 255;
for (var m = 0; m < 6; ++m) {
var n = k + m * attribs.color.itemSize;
attribs.color.data[n+0] = r;
attribs.color.data[n+1] = g;
attribs.color.data[n+2] = b;
attribs.bgColor.data[n+0] = br;
attribs.bgColor.data[n+1] = bg;
attribs.bgColor.data[n+2] = bb;
attribs.charIndex.data[kk+m] = ch;
}
}
}
// Upload
if (newChars) this.buildTexture();
gl.bindBuffer(gl.ARRAY_BUFFER, attribs.color.buffer);
gl.bufferData(gl.ARRAY_BUFFER, attribs.color.data, attribs.color.hint);
gl.bindBuffer(gl.ARRAY_BUFFER, attribs.bgColor.buffer);
gl.bufferData(gl.ARRAY_BUFFER, attribs.bgColor.data, attribs.bgColor.hint);
gl.bindBuffer(gl.ARRAY_BUFFER, attribs.charIndex.buffer);
gl.bufferData(gl.ARRAY_BUFFER, attribs.charIndex.data, attribs.charIndex.hint);
var attrib = this.attribs.position;
gl.drawArrays(gl.TRIANGLES, 0, attrib.data.length / attrib.itemSize);
};
ut.WebGLRenderer.VERTEX_SHADER = [
"attribute vec2 position;",
"attribute vec2 texCoord;",
"attribute vec3 color;",
"attribute vec3 bgColor;",
"attribute float charIndex;",
"uniform vec2 uResolution;",
"uniform vec2 uTileCounts;",
"uniform vec2 uPadding;",
"varying vec2 vTexCoord;",
"varying vec3 vColor;",
"varying vec3 vBgColor;",
"void main() {",
"vec2 tileCoords = floor(vec2(mod(charIndex, uTileCounts.x), charIndex / uTileCounts.x));",
"vTexCoord = (texCoord + tileCoords) / uTileCounts;",
"vTexCoord += (0.5 - texCoord) * uPadding;",
"vColor = color;",
"vBgColor = bgColor;",
"vec2 pos = position / uResolution * 2.0 - 1.0;",
"gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0);",
"}"
].join('\n');
ut.WebGLRenderer.FRAGMENT_SHADER = [
"precision mediump float;",
"uniform sampler2D uFont;",
"varying vec2 vTexCoord;",
"varying vec3 vColor;",
"varying vec3 vBgColor;",
"void main() {",
"vec4 color = texture2D(uFont, vTexCoord);",
"color.rgb = mix(vBgColor, vColor, color.rgb);",
"gl_FragColor = color;",
"}"
].join('\n');
================================================
FILE: examples/presentations.md
================================================
# RxJS Presentations #
The following are presentations about RxJS
- Don't Cross the Streams - Cascadia.js 2012 [slides/demos](http://www.slideshare.net/mattpodwysocki/cascadiajs-dont-cross-the-streams) | [video](http://www.youtube.com/watch?v=FqBq4uoiG0M)
- Curing Your Asynchronous Blues - Strange Loop 2013 [slides/demos](https://github.com/Reactive-Extensions/StrangeLoop2013) | [video](http://www.infoq.com/presentations/rx-event-processing)
- Streaming and event-based programming using FRP and RxJS - FutureJS 2014 [slides/demos](https://github.com/Reactive-Extensions/FutureJS) | [video](https://www.youtube.com/watch?v=zlERo_JMGCw)
- [Tyrannosaurus Rx](http://yobriefca.se/presentations/tyrannosaurus-rx.pdf) - [James Hughes](http://twitter.com/kouphax)
- Taming Asynchronous Workflows with Functional Reactive Programming - EuroClojure - [Leonardo Borges](https://twitter.com/leonardo_borges) [slides](http://www.slideshare.net/borgesleonardo/functional-reactive-programming-compositional-event-systems) | [video](http://www.slideshare.net/borgesleonardo/functional-reactive-programming-compositional-event-systems)
- Reactive All the Things - ng-conf 2015 - [Martin Gontovnikas](https://twitter.com/mgonto/) & [Ben Lesh](https://twitter.com/BenLesh)
- [Slides](http://mgonto.github.io/reactive-all-the-things-talk/#1)
- [Video](https://www.youtube.com/watch?v=zbBVG8bOoXk&feature=youtu.be&app=desktop)
- The Reactive Loop - Functional JS London 2015
- [Slides](http://slides.com/theefer/reactive-loop-funjs#/)
- [Code](https://github.com/theefer/funjs-reactive-loop)
- Reactive Functions with RxJS - Leeds JS 2015
- [Slides](https://www.icloud.com/keynote/AwBWCAESEIf9pea2IykiVtOZFiXflDsaKj9lVsSLP_OtPU29v7fNpMs78DK7tvXz4bFBkb6BXFKjxqt4G5B_UlM6TwMCUCAQEEIGVYVFig5qOTdorTOd2ERMJDtn6dvDFY58zqBiVzZmtN#RxJS_talk)
================================================
FILE: examples/readme.md
================================================
# The Reactive Extensions for JavaScript (RxJS) Examples #
The Reactive Extensions for JavaScript have a number of examples that highlight the unique capabilities of the library.
================================================
FILE: examples/requirejs/js/app/main.js
================================================
require(['rx', 'rx.binding', 'rx.time', 'rx.dom'], function (Rx) {
var coords = document.querySelector('#coordinates');
var delta = document.querySelector('#delta');
var buffer = document.querySelector('#buffer');
// One and only one subscription
var mousemove = Rx.DOM.fromEvent(document, 'mousemove');
// Simple coordinates
var d1 = mousemove.subscribe(function (e) {
coords.innerHTML = e.clientX + ',' + e.clientY;
});
// Calculate deltas between two mouse movements
var d2 = mousemove.zip(
mousemove.skip(1),
function (l, r) {
return { clientX: r.clientX - l.clientX, clientY: r.clientY - l.clientY };
})
.subscribe(function (e) {
delta.innerHTML = e.clientX + ',' + e.clientY;
}
);
// Get the last 500ms worth of mouse moves or 10, whichever comes first
var d3 = mousemove.bufferWithTimeOrCount(500, 10).subscribe(function (e) {
while(buffer.firstChild) {
buffer.removeChild(buffer.firstChild);
}
var node, elem, i, len;
for(i = 0, len = e.length; i < len; i++) {
elem = e[i];
node = document.createElement('li');
node.innerHTML = elem.clientX + ',' + elem.clientY;
buffer.appendChild(node);
}
});
});
================================================
FILE: examples/requirejs/js/app.js
================================================
requirejs.config({
"baseUrl": "js/lib",
"paths": {
"app": "../app",
"rx": "http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.18/rx",
"rx.binding": "http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.18/rx.binding",
"rx.time": "http://cdnjs.cloudflare.com/ajax/libs/rxjs/2.1.18/rx.time",
"rx.dom": "http://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/2.0.7/rx.dom"
}
});
// Load the main app module to start the app
requirejs(["app/main"]);
================================================
FILE: examples/requirejs/js/lib/require.js
================================================
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.0.6 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
*/
//Not using strict: uneven strict support in browsers, #392, and causes
//problems with requirejs.exec()/transpiler plugins that may not be strict.
/*jslint regexp: true, nomen: true, sloppy: true */
/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
var requirejs, require, define;
(function (global) {
var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.0.6',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/,
currDirRegExp = /^\.\//,
op = Object.prototype,
ostring = op.toString,
hasOwn = op.hasOwnProperty,
ap = Array.prototype,
aps = ap.slice,
apsp = ap.splice,
isBrowser = !!(typeof window !== 'undefined' && navigator && document),
isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
//PS3 indicates loaded and complete, but need to wait for complete
//specifically. Sequence is 'loading', 'loaded', execution,
// then 'complete'. The UA check is unfortunate, but not sure how
//to feature test w/o causing perf issues.
readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
/^complete$/ : /^(complete|loaded)$/,
defContextName = '_',
//Oh the tragedy, detecting opera. See the usage of isOpera for reason.
isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
contexts = {},
cfg = {},
globalDefQueue = [],
useInteractive = false;
function isFunction(it) {
return ostring.call(it) === '[object Function]';
}
function isArray(it) {
return ostring.call(it) === '[object Array]';
}
/**
* Helper function for iterating over an array. If the func returns
* a true value, it will break out of the loop.
*/
function each(ary, func) {
if (ary) {
var i;
for (i = 0; i < ary.length; i += 1) {
if (ary[i] && func(ary[i], i, ary)) {
break;
}
}
}
}
/**
* Helper function for iterating over an array backwards. If the func
* returns a true value, it will break out of the loop.
*/
function eachReverse(ary, func) {
if (ary) {
var i;
for (i = ary.length - 1; i > -1; i -= 1) {
if (ary[i] && func(ary[i], i, ary)) {
break;
}
}
}
}
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
/**
* Cycles over properties in an object and calls a function for each
* property value. If the function returns a truthy value, then the
* iteration is stopped.
*/
function eachProp(obj, func) {
var prop;
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (func(obj[prop], prop)) {
break;
}
}
}
}
/**
* Simple function to mix in properties from source into target,
* but only if target does not already have a property of the same name.
* This is not robust in IE for transferring methods that match
* Object.prototype names, but the uses of mixin here seem unlikely to
* trigger a problem related to that.
*/
function mixin(target, source, force, deepStringMixin) {
if (source) {
eachProp(source, function (value, prop) {
if (force || !hasProp(target, prop)) {
if (deepStringMixin && typeof value !== 'string') {
if (!target[prop]) {
target[prop] = {};
}
mixin(target[prop], value, force, deepStringMixin);
} else {
target[prop] = value;
}
}
});
}
return target;
}
//Similar to Function.prototype.bind, but the 'this' object is specified
//first, since it is easier to read/figure out what 'this' will be.
function bind(obj, fn) {
return function () {
return fn.apply(obj, arguments);
};
}
function scripts() {
return document.getElementsByTagName('script');
}
//Allow getting a global that expressed in
//dot notation, like 'a.b.c'.
function getGlobal(value) {
if (!value) {
return value;
}
var g = global;
each(value.split('.'), function (part) {
g = g[part];
});
return g;
}
function makeContextModuleFunc(func, relMap, enableBuildCallback) {
return function () {
//A version of a require function that passes a moduleName
//value for items that may need to
//look up paths relative to the moduleName
var args = aps.call(arguments, 0), lastArg;
if (enableBuildCallback &&
isFunction((lastArg = args[args.length - 1]))) {
lastArg.__requireJsBuild = true;
}
args.push(relMap);
return func.apply(null, args);
};
}
function addRequireMethods(req, context, relMap) {
each([
['toUrl'],
['undef'],
['defined', 'requireDefined'],
['specified', 'requireSpecified']
], function (item) {
var prop = item[1] || item[0];
req[item[0]] = context ? makeContextModuleFunc(context[prop], relMap) :
//If no context, then use default context. Reference from
//contexts instead of early binding to default context, so
//that during builds, the latest instance of the default
//context with its config gets used.
function () {
var ctx = contexts[defContextName];
return ctx[prop].apply(ctx, arguments);
};
});
}
/**
* Constructs an error with a pointer to an URL with more information.
* @param {String} id the error ID that maps to an ID on a web page.
* @param {String} message human readable error.
* @param {Error} [err] the original error, if there is one.
*
* @returns {Error}
*/
function makeError(id, msg, err, requireModules) {
var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
e.requireType = id;
e.requireModules = requireModules;
if (err) {
e.originalError = err;
}
return e;
}
if (typeof define !== 'undefined') {
//If a define is already in play via another AMD loader,
//do not overwrite.
return;
}
if (typeof requirejs !== 'undefined') {
if (isFunction(requirejs)) {
//Do not overwrite and existing requirejs instance.
return;
}
cfg = requirejs;
requirejs = undefined;
}
//Allow for a require config object
if (typeof require !== 'undefined' && !isFunction(require)) {
//assume it is a config object.
cfg = require;
require = undefined;
}
function newContext(contextName) {
var inCheckLoaded, Module, context, handlers,
checkLoadedTimeoutId,
config = {
waitSeconds: 7,
baseUrl: './',
paths: {},
pkgs: {},
shim: {}
},
registry = {},
undefEvents = {},
defQueue = [],
defined = {},
urlFetched = {},
requireCounter = 1,
unnormalizedCounter = 1,
//Used to track the order in which modules
//should be executed, by the order they
//load. Important for consistent cycle resolution
//behavior.
waitAry = [];
/**
* Trims the . and .. from an array of path segments.
* It will keep a leading path segment if a .. will become
* the first path segment, to help with module name lookups,
* which act like paths, but can be remapped. But the end result,
* all paths that use this function should look normalized.
* NOTE: this method MODIFIES the input array.
* @param {Array} ary the array of path segments.
*/
function trimDots(ary) {
var i, part;
for (i = 0; ary[i]; i += 1) {
part = ary[i];
if (part === '.') {
ary.splice(i, 1);
i -= 1;
} else if (part === '..') {
if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
//End of the line. Keep at least one non-dot
//path segment at the front so it can be mapped
//correctly to disk. Otherwise, there is likely
//no path mapping for a path starting with '..'.
//This can still fail, but catches the most reasonable
//uses of ..
break;
} else if (i > 0) {
ary.splice(i - 1, 2);
i -= 2;
}
}
}
}
/**
* Given a relative module name, like ./something, normalize it to
* a real name that can be mapped to a path.
* @param {String} name the relative name
* @param {String} baseName a real name that the name arg is relative
* to.
* @param {Boolean} applyMap apply the map config to the value. Should
* only be done if this normalization is for a dependency ID.
* @returns {String} normalized name
*/
function normalize(name, baseName, applyMap) {
var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
foundMap, foundI, foundStarMap, starI,
baseParts = baseName && baseName.split('/'),
normalizedBaseParts = baseParts,
map = config.map,
starMap = map && map['*'];
//Adjust any relative paths.
if (name && name.charAt(0) === '.') {
//If have a base name, try to normalize against it,
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
if (config.pkgs[baseName]) {
//If the baseName is a package name, then just treat it as one
//name to concat the name with.
normalizedBaseParts = baseParts = [baseName];
} else {
//Convert baseName to array, and lop off the last part,
//so that . matches that 'directory' and not name of the baseName's
//module. For instance, baseName of 'one/two/three', maps to
//'one/two/three.js', but we want the directory, 'one/two' for
//this normalization.
normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
}
name = normalizedBaseParts.concat(name.split('/'));
trimDots(name);
//Some use of packages may use a . path to reference the
//'main' module name, so normalize for that.
pkgConfig = config.pkgs[(pkgName = name[0])];
name = name.join('/');
if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
name = pkgName;
}
} else if (name.indexOf('./') === 0) {
// No baseName, so this is ID is resolved relative
// to baseUrl, pull off the leading dot.
name = name.substring(2);
}
}
//Apply map config if available.
if (applyMap && (baseParts || starMap) && map) {
nameParts = name.split('/');
for (i = nameParts.length; i > 0; i -= 1) {
nameSegment = nameParts.slice(0, i).join('/');
if (baseParts) {
//Find the longest baseName segment match in the config.
//So, do joins on the biggest to smallest lengths of baseParts.
for (j = baseParts.length; j > 0; j -= 1) {
mapValue = map[baseParts.slice(0, j).join('/')];
//baseName segment has config, find if it has one for
//this name.
if (mapValue) {
mapValue = mapValue[nameSegment];
if (mapValue) {
//Match, update name to the new value.
foundMap = mapValue;
foundI = i;
break;
}
}
}
}
if (foundMap) {
break;
}
//Check for a star map match, but just hold on to it,
//if there is a shorter segment match later in a matching
//config, then favor over this star map.
if (!foundStarMap && starMap && starMap[nameSegment]) {
foundStarMap = starMap[nameSegment];
starI = i;
}
}
if (!foundMap && foundStarMap) {
foundMap = foundStarMap;
foundI = starI;
}
if (foundMap) {
nameParts.splice(0, foundI, foundMap);
name = nameParts.join('/');
}
}
return name;
}
function removeScript(name) {
if (isBrowser) {
each(scripts(), function (scriptNode) {
if (scriptNode.getAttribute('data-requiremodule') === name &&
scriptNode.getAttribute('data-requirecontext') === context.contextName) {
scriptNode.parentNode.removeChild(scriptNode);
return true;
}
});
}
}
function hasPathFallback(id) {
var pathConfig = config.paths[id];
if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
removeScript(id);
//Pop off the first array value, since it failed, and
//retry
pathConfig.shift();
context.undef(id);
context.require([id]);
return true;
}
}
/**
* Creates a module mapping that includes plugin prefix, module
* name, and path. If parentModuleMap is provided it will
* also normalize the name via require.normalize()
*
* @param {String} name the module name
* @param {String} [parentModuleMap] parent module map
* for the module name, used to resolve relative names.
* @param {Boolean} isNormalized: is the ID already normalized.
* This is true if this call is done for a define() module ID.
* @param {Boolean} applyMap: apply the map config to the ID.
* Should only be true if this map is for a dependency.
*
* @returns {Object}
*/
function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
var url, pluginModule, suffix,
index = name ? name.indexOf('!') : -1,
prefix = null,
parentName = parentModuleMap ? parentModuleMap.name : null,
originalName = name,
isDefine = true,
normalizedName = '';
//If no name, then it means it is a require call, generate an
//internal name.
if (!name) {
isDefine = false;
name = '_@r' + (requireCounter += 1);
}
if (index !== -1) {
prefix = name.substring(0, index);
name = name.substring(index + 1, name.length);
}
if (prefix) {
prefix = normalize(prefix, parentName, applyMap);
pluginModule = defined[prefix];
}
//Account for relative paths if there is a base name.
if (name) {
if (prefix) {
if (pluginModule && pluginModule.normalize) {
//Plugin is loaded, use its normalize method.
normalizedName = pluginModule.normalize(name, function (name) {
return normalize(name, parentName, applyMap);
});
} else {
normalizedName = normalize(name, parentName, applyMap);
}
} else {
//A regular module.
normalizedName = normalize(name, parentName, applyMap);
url = context.nameToUrl(normalizedName);
}
}
//If the id is a plugin id that cannot be determined if it needs
//normalization, stamp it with a unique ID so two matching relative
//ids that may conflict can be separate.
suffix = prefix && !pluginModule && !isNormalized ?
'_unnormalized' + (unnormalizedCounter += 1) :
'';
return {
prefix: prefix,
name: normalizedName,
parentMap: parentModuleMap,
unnormalized: !!suffix,
url: url,
originalName: originalName,
isDefine: isDefine,
id: (prefix ?
prefix + '!' + normalizedName :
normalizedName) + suffix
};
}
function getModule(depMap) {
var id = depMap.id,
mod = registry[id];
if (!mod) {
mod = registry[id] = new context.Module(depMap);
}
return mod;
}
function on(depMap, name, fn) {
var id = depMap.id,
mod = registry[id];
if (hasProp(defined, id) &&
(!mod || mod.defineEmitComplete)) {
if (name === 'defined') {
fn(defined[id]);
}
} else {
getModule(depMap).on(name, fn);
}
}
function onError(err, errback) {
var ids = err.requireModules,
notified = false;
if (errback) {
errback(err);
} else {
each(ids, function (id) {
var mod = registry[id];
if (mod) {
//Set error on module, so it skips timeout checks.
mod.error = err;
if (mod.events.error) {
notified = true;
mod.emit('error', err);
}
}
});
if (!notified) {
req.onError(err);
}
}
}
/**
* Internal method to transfer globalQueue items to this context's
* defQueue.
*/
function takeGlobalQueue() {
//Push all the globalDefQueue items into the context's defQueue
if (globalDefQueue.length) {
//Array splice in the values since the context code has a
//local var ref to defQueue, so cannot just reassign the one
//on context.
apsp.apply(defQueue,
[defQueue.length - 1, 0].concat(globalDefQueue));
globalDefQueue = [];
}
}
/**
* Helper function that creates a require function object to give to
* modules that ask for it as a dependency. It needs to be specific
* per module because of the implication of path mappings that may
* need to be relative to the module name.
*/
function makeRequire(mod, enableBuildCallback, altRequire) {
var relMap = mod && mod.map,
modRequire = makeContextModuleFunc(altRequire || context.require,
relMap,
enableBuildCallback);
addRequireMethods(modRequire, context, relMap);
modRequire.isBrowser = isBrowser;
return modRequire;
}
handlers = {
'require': function (mod) {
return makeRequire(mod);
},
'exports': function (mod) {
mod.usingExports = true;
if (mod.map.isDefine) {
return (mod.exports = defined[mod.map.id] = {});
}
},
'module': function (mod) {
return (mod.module = {
id: mod.map.id,
uri: mod.map.url,
config: function () {
return (config.config && config.config[mod.map.id]) || {};
},
exports: defined[mod.map.id]
});
}
};
function removeWaiting(id) {
//Clean up machinery used for waiting modules.
delete registry[id];
each(waitAry, function (mod, i) {
if (mod.map.id === id) {
waitAry.splice(i, 1);
if (!mod.defined) {
context.waitCount -= 1;
}
return true;
}
});
}
function findCycle(mod, traced, processed) {
var id = mod.map.id,
depArray = mod.depMaps,
foundModule;
//Do not bother with unitialized modules or not yet enabled
//modules.
if (!mod.inited) {
return;
}
//Found the cycle.
if (traced[id]) {
return mod;
}
traced[id] = true;
//Trace through the dependencies.
each(depArray, function (depMap) {
var depId = depMap.id,
depMod = registry[depId];
if (!depMod || processed[depId] ||
!depMod.inited || !depMod.enabled) {
return;
}
return (foundModule = findCycle(depMod, traced, processed));
});
processed[id] = true;
return foundModule;
}
function forceExec(mod, traced, uninited) {
var id = mod.map.id,
depArray = mod.depMaps;
if (!mod.inited || !mod.map.isDefine) {
return;
}
if (traced[id]) {
return defined[id];
}
traced[id] = mod;
each(depArray, function (depMap) {
var depId = depMap.id,
depMod = registry[depId],
value;
if (handlers[depId]) {
return;
}
if (depMod) {
if (!depMod.inited || !depMod.enabled) {
//Dependency is not inited,
//so this module cannot be
//given a forced value yet.
uninited[id] = true;
return;
}
//Get the value for the current dependency
value = forceExec(depMod, traced, uninited);
//Even with forcing it may not be done,
//in particular if the module is waiting
//on a plugin resource.
if (!uninited[depId]) {
mod.defineDepById(depId, value);
}
}
});
mod.check(true);
return defined[id];
}
function modCheck(mod) {
mod.check();
}
function checkLoaded() {
var map, modId, err, usingPathFallback,
waitInterval = config.waitSeconds * 1000,
//It is possible to disable the wait interval by using waitSeconds of 0.
expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
noLoads = [],
stillLoading = false,
needCycleCheck = true;
//Do not bother if this call was a result of a cycle break.
if (inCheckLoaded) {
return;
}
inCheckLoaded = true;
//Figure out the state of all the modules.
eachProp(registry, function (mod) {
map = mod.map;
modId = map.id;
//Skip things that are not enabled or in error state.
if (!mod.enabled) {
return;
}
if (!mod.error) {
//If the module should be executed, and it has not
//been inited and time is up, remember it.
if (!mod.inited && expired) {
if (hasPathFallback(modId)) {
usingPathFallback = true;
stillLoading = true;
} else {
noLoads.push(modId);
removeScript(modId);
}
} else if (!mod.inited && mod.fetched && map.isDefine) {
stillLoading = true;
if (!map.prefix) {
//No reason to keep looking for unfinished
//loading. If the only stillLoading is a
//plugin resource though, keep going,
//because it may be that a plugin resource
//is waiting on a non-plugin cycle.
return (needCycleCheck = false);
}
}
}
});
if (expired && noLoads.length) {
//If wait time expired, throw error of unloaded modules.
err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
err.contextName = context.contextName;
return onError(err);
}
//Not expired, check for a cycle.
if (needCycleCheck) {
each(waitAry, function (mod) {
if (mod.defined) {
return;
}
var cycleMod = findCycle(mod, {}, {}),
traced = {};
if (cycleMod) {
forceExec(cycleMod, traced, {});
//traced modules may have been
//removed from the registry, but
//their listeners still need to
//be called.
eachProp(traced, modCheck);
}
});
//Now that dependencies have
//been satisfied, trigger the
//completion check that then
//notifies listeners.
eachProp(registry, modCheck);
}
//If still waiting on loads, and the waiting load is something
//other than a plugin resource, or there are still outstanding
//scripts, then just try back later.
if ((!expired || usingPathFallback) && stillLoading) {
//Something is still waiting to load. Wait for it, but only
//if a timeout is not already in effect.
if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
checkLoadedTimeoutId = setTimeout(function () {
checkLoadedTimeoutId = 0;
checkLoaded();
}, 50);
}
}
inCheckLoaded = false;
}
Module = function (map) {
this.events = undefEvents[map.id] || {};
this.map = map;
this.shim = config.shim[map.id];
this.depExports = [];
this.depMaps = [];
this.depMatched = [];
this.pluginMaps = {};
this.depCount = 0;
/* this.exports this.factory
this.depMaps = [],
this.enabled, this.fetched
*/
};
Module.prototype = {
init: function (depMaps, factory, errback, options) {
options = options || {};
//Do not do more inits if already done. Can happen if there
//are multiple define calls for the same module. That is not
//a normal, common case, but it is also not unexpected.
if (this.inited) {
return;
}
this.factory = factory;
if (errback) {
//Register for errors on this module.
this.on('error', errback);
} else if (this.events.error) {
//If no errback already, but there are error listeners
//on this module, set up an errback to pass to the deps.
errback = bind(this, function (err) {
this.emit('error', err);
});
}
//Do a copy of the dependency array, so that
//source inputs are not modified. For example
//"shim" deps are passed in here directly, and
//doing a direct modification of the depMaps array
//would affect that config.
this.depMaps = depMaps && depMaps.slice(0);
this.depMaps.rjsSkipMap = depMaps.rjsSkipMap;
this.errback = errback;
//Indicate this module has be initialized
this.inited = true;
this.ignore = options.ignore;
//Could have option to init this module in enabled mode,
//or could have been previously marked as enabled. However,
//the dependencies are not known until init is called. So
//if enabled previously, now trigger dependencies as enabled.
if (options.enabled || this.enabled) {
//Enable this module and dependencies.
//Will call this.check()
this.enable();
} else {
this.check();
}
},
defineDepById: function (id, depExports) {
var i;
//Find the index for this dependency.
each(this.depMaps, function (map, index) {
if (map.id === id) {
i = index;
return true;
}
});
return this.defineDep(i, depExports);
},
defineDep: function (i, depExports) {
//Because of cycles, defined callback for a given
//export can be called more than once.
if (!this.depMatched[i]) {
this.depMatched[i] = true;
this.depCount -= 1;
this.depExports[i] = depExports;
}
},
fetch: function () {
if (this.fetched) {
return;
}
this.fetched = true;
context.startTime = (new Date()).getTime();
var map = this.map;
//If the manager is for a plugin managed resource,
//ask the plugin to load it now.
if (this.shim) {
makeRequire(this, true)(this.shim.deps || [], bind(this, function () {
return map.prefix ? this.callPlugin() : this.load();
}));
} else {
//Regular dependency.
return map.prefix ? this.callPlugin() : this.load();
}
},
load: function () {
var url = this.map.url;
//Regular dependency.
if (!urlFetched[url]) {
urlFetched[url] = true;
context.load(this.map.id, url);
}
},
/**
* Checks is the module is ready to define itself, and if so,
* define it. If the silent argument is true, then it will just
* define, but not notify listeners, and not ask for a context-wide
* check of all loaded modules. That is useful for cycle breaking.
*/
check: function (silent) {
if (!this.enabled || this.enabling) {
return;
}
var err, cjsModule,
id = this.map.id,
depExports = this.depExports,
exports = this.exports,
factory = this.factory;
if (!this.inited) {
this.fetch();
} else if (this.error) {
this.emit('error', this.error);
} else if (!this.defining) {
//The factory could trigger another require call
//that would result in checking this module to
//define itself again. If already in the process
//of doing that, skip this work.
this.defining = true;
if (this.depCount < 1 && !this.defined) {
if (isFunction(factory)) {
//If there is an error listener, favor passing
//to that instead of throwing an error.
if (this.events.error) {
try {
exports = context.execCb(id, factory, depExports, exports);
} catch (e) {
err = e;
}
} else {
exports = context.execCb(id, factory, depExports, exports);
}
if (this.map.isDefine) {
//If setting exports via 'module' is in play,
//favor that over return value and exports. After that,
//favor a non-undefined return value over exports use.
cjsModule = this.module;
if (cjsModule &&
cjsModule.exports !== undefined &&
//Make sure it is not already the exports value
cjsModule.exports !== this.exports) {
exports = cjsModule.exports;
} else if (exports === undefined && this.usingExports) {
//exports already set the defined value.
exports = this.exports;
}
}
if (err) {
err.requireMap = this.map;
err.requireModules = [this.map.id];
err.requireType = 'define';
return onError((this.error = err));
}
} else {
//Just a literal value
exports = factory;
}
this.exports = exports;
if (this.map.isDefine && !this.ignore) {
defined[id] = exports;
if (req.onResourceLoad) {
req.onResourceLoad(context, this.map, this.depMaps);
}
}
//Clean up
delete registry[id];
this.defined = true;
context.waitCount -= 1;
if (context.waitCount === 0) {
//Clear the wait array used for cycles.
waitAry = [];
}
}
//Finished the define stage. Allow calling check again
//to allow define notifications below in the case of a
//cycle.
this.defining = false;
if (!silent) {
if (this.defined && !this.defineEmitted) {
this.defineEmitted = true;
this.emit('defined', this.exports);
this.defineEmitComplete = true;
}
}
}
},
callPlugin: function () {
var map = this.map,
id = map.id,
pluginMap = makeModuleMap(map.prefix, null, false, true);
on(pluginMap, 'defined', bind(this, function (plugin) {
var load, normalizedMap, normalizedMod,
name = this.map.name,
parentName = this.map.parentMap ? this.map.parentMap.name : null;
//If current map is not normalized, wait for that
//normalized name to load instead of continuing.
if (this.map.unnormalized) {
//Normalize the ID if the plugin allows it.
if (plugin.normalize) {
name = plugin.normalize(name, function (name) {
return normalize(name, parentName, true);
}) || '';
}
normalizedMap = makeModuleMap(map.prefix + '!' + name,
this.map.parentMap,
false,
true);
on(normalizedMap,
'defined', bind(this, function (value) {
this.init([], function () { return value; }, null, {
enabled: true,
ignore: true
});
}));
normalizedMod = registry[normalizedMap.id];
if (normalizedMod) {
if (this.events.error) {
normalizedMod.on('error', bind(this, function (err) {
this.emit('error', err);
}));
}
normalizedMod.enable();
}
return;
}
load = bind(this, function (value) {
this.init([], function () { return value; }, null, {
enabled: true
});
});
load.error = bind(this, function (err) {
this.inited = true;
this.error = err;
err.requireModules = [id];
//Remove temp unnormalized modules for this module,
//since they will never be resolved otherwise now.
eachProp(registry, function (mod) {
if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
removeWaiting(mod.map.id);
}
});
onError(err);
});
//Allow plugins to load other code without having to know the
//context or how to 'complete' the load.
load.fromText = function (moduleName, text) {
/*jslint evil: true */
var hasInteractive = useInteractive;
//Turn off interactive script matching for IE for any define
//calls in the text, then turn it back on at the end.
if (hasInteractive) {
useInteractive = false;
}
//Prime the system by creating a module instance for
//it.
getModule(makeModuleMap(moduleName));
req.exec(text);
if (hasInteractive) {
useInteractive = true;
}
//Support anonymous modules.
context.completeLoad(moduleName);
};
//Use parentName here since the plugin's name is not reliable,
//could be some weird string with no path that actually wants to
//reference the parentName's path.
plugin.load(map.name, makeRequire(map.parentMap, true, function (deps, cb, er) {
deps.rjsSkipMap = true;
return context.require(deps, cb, er);
}), load, config);
}));
context.enable(pluginMap, this);
this.pluginMaps[pluginMap.id] = pluginMap;
},
enable: function () {
this.enabled = true;
if (!this.waitPushed) {
waitAry.push(this);
context.waitCount += 1;
this.waitPushed = true;
}
//Set flag mentioning that the module is enabling,
//so that immediate calls to the defined callbacks
//for dependencies do not trigger inadvertent load
//with the depCount still being zero.
this.enabling = true;
//Enable each dependency
each(this.depMaps, bind(this, function (depMap, i) {
var id, mod, handler;
if (typeof depMap === 'string') {
//Dependency needs to be converted to a depMap
//and wired up to this module.
depMap = makeModuleMap(depMap,
(this.map.isDefine ? this.map : this.map.parentMap),
false,
!this.depMaps.rjsSkipMap);
this.depMaps[i] = depMap;
handler = handlers[depMap.id];
if (handler) {
this.depExports[i] = handler(this);
return;
}
this.depCount += 1;
on(depMap, 'defined', bind(this, function (depExports) {
this.defineDep(i, depExports);
this.check();
}));
if (this.errback) {
on(depMap, 'error', this.errback);
}
}
id = depMap.id;
mod = registry[id];
//Skip special modules like 'require', 'exports', 'module'
//Also, don't call enable if it is already enabled,
//important in circular dependency cases.
if (!handlers[id] && mod && !mod.enabled) {
context.enable(depMap, this);
}
}));
//Enable each plugin that is used in
//a dependency
eachProp(this.pluginMaps, bind(this, function (pluginMap) {
var mod = registry[pluginMap.id];
if (mod && !mod.enabled) {
context.enable(pluginMap, this);
}
}));
this.enabling = false;
this.check();
},
on: function (name, cb) {
var cbs = this.events[name];
if (!cbs) {
cbs = this.events[name] = [];
}
cbs.push(cb);
},
emit: function (name, evt) {
each(this.events[name], function (cb) {
cb(evt);
});
if (name === 'error') {
//Now that the error handler was triggered, remove
//the listeners, since this broken Module instance
//can stay around for a while in the registry/waitAry.
delete this.events[name];
}
}
};
function callGetModule(args) {
getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
}
function removeListener(node, func, name, ieName) {
//Favor detachEvent because of IE9
//issue, see attachEvent/addEventListener comment elsewhere
//in this file.
if (node.detachEvent && !isOpera) {
//Probably IE. If not it will throw an error, which will be
//useful to know.
if (ieName) {
node.detachEvent(ieName, func);
}
} else {
node.removeEventListener(name, func, false);
}
}
/**
* Given an event from a script node, get the requirejs info from it,
* and then removes the event listeners on the node.
* @param {Event} evt
* @returns {Object}
*/
function getScriptData(evt) {
//Using currentTarget instead of target for Firefox 2.0's sake. Not
//all old browsers will be supported, but this one was easy enough
//to support and still makes sense.
var node = evt.currentTarget || evt.srcElement;
//Remove the listeners once here.
removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
removeListener(node, context.onScriptError, 'error');
return {
node: node,
id: node && node.getAttribute('data-requiremodule')
};
}
return (context = {
config: config,
contextName: contextName,
registry: registry,
defined: defined,
urlFetched: urlFetched,
waitCount: 0,
defQueue: defQueue,
Module: Module,
makeModuleMap: makeModuleMap,
/**
* Set a configuration for the context.
* @param {Object} cfg config object to integrate.
*/
configure: function (cfg) {
//Make sure the baseUrl ends in a slash.
if (cfg.baseUrl) {
if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
cfg.baseUrl += '/';
}
}
//Save off the paths and packages since they require special processing,
//they are additive.
var pkgs = config.pkgs,
shim = config.shim,
paths = config.paths,
map = config.map;
//Mix in the config values, favoring the new values over
//existing ones in context.config.
mixin(config, cfg, true);
//Merge paths.
config.paths = mixin(paths, cfg.paths, true);
//Merge map
if (cfg.map) {
config.map = mixin(map || {}, cfg.map, true, true);
}
//Merge shim
if (cfg.shim) {
eachProp(cfg.shim, function (value, id) {
//Normalize the structure
if (isArray(value)) {
value = {
deps: value
};
}
if (value.exports && !value.exports.__buildReady) {
value.exports = context.makeShimExports(value.exports);
}
shim[id] = value;
});
config.shim = shim;
}
//Adjust packages if necessary.
if (cfg.packages) {
each(cfg.packages, function (pkgObj) {
var location;
pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
location = pkgObj.location;
//Create a brand new object on pkgs, since currentPackages can
//be passed in again, and config.pkgs is the internal transformed
//state for all package configs.
pkgs[pkgObj.name] = {
name: pkgObj.name,
location: location || pkgObj.name,
//Remove leading dot in main, so main paths are normalized,
//and remove any trailing .js, since different package
//envs have different conventions: some use a module name,
//some use a file name.
main: (pkgObj.main || 'main')
.replace(currDirRegExp, '')
.replace(jsSuffixRegExp, '')
};
});
//Done with modifications, assing packages back to context config
config.pkgs = pkgs;
}
//If there are any "waiting to execute" modules in the registry,
//update the maps for them, since their info, like URLs to load,
//may have changed.
eachProp(registry, function (mod, id) {
//If module already has init called, since it is too
//late to modify them, and ignore unnormalized ones
//since they are transient.
if (!mod.inited && !mod.map.unnormalized) {
mod.map = makeModuleMap(id);
}
});
//If a deps array or a config callback is specified, then call
//require with those args. This is useful when require is defined as a
//config object before require.js is loaded.
if (cfg.deps || cfg.callback) {
context.require(cfg.deps || [], cfg.callback);
}
},
makeShimExports: function (exports) {
var func;
if (typeof exports === 'string') {
func = function () {
return getGlobal(exports);
};
//Save the exports for use in nodefine checking.
func.exports = exports;
return func;
} else {
return function () {
return exports.apply(global, arguments);
};
}
},
requireDefined: function (id, relMap) {
return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
},
requireSpecified: function (id, relMap) {
id = makeModuleMap(id, relMap, false, true).id;
return hasProp(defined, id) || hasProp(registry, id);
},
require: function (deps, callback, errback, relMap) {
var moduleName, id, map, requireMod, args;
if (typeof deps === 'string') {
if (isFunction(callback)) {
//Invalid call
return onError(makeError('requireargs', 'Invalid require call'), errback);
}
//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
//In this case deps is the moduleName and callback is
//the relMap
if (req.get) {
return req.get(context, deps, callback);
}
//Just return the module wanted. In this scenario, the
//second arg (if passed) is just the relMap.
moduleName = deps;
relMap = callback;
//Normalize module name, if it contains . or ..
map = makeModuleMap(moduleName, relMap, false, true);
id = map.id;
if (!hasProp(defined, id)) {
return onError(makeError('notloaded', 'Module name "' +
id +
'" has not been loaded yet for context: ' +
contextName));
}
return defined[id];
}
//Callback require. Normalize args. if callback or errback is
//not a function, it means it is a relMap. Test errback first.
if (errback && !isFunction(errback)) {
relMap = errback;
errback = undefined;
}
if (callback && !isFunction(callback)) {
relMap = callback;
callback = undefined;
}
//Any defined modules in the global queue, intake them now.
takeGlobalQueue();
//Make sure any remaining defQueue items get properly processed.
while (defQueue.length) {
args = defQueue.shift();
if (args[0] === null) {
return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
} else {
//args are id, deps, factory. Should be normalized by the
//define() function.
callGetModule(args);
}
}
//Mark all the dependencies as needing to be loaded.
requireMod = getModule(makeModuleMap(null, relMap));
requireMod.init(deps, callback, errback, {
enabled: true
});
checkLoaded();
return context.require;
},
undef: function (id) {
//Bind any waiting define() calls to this context,
//fix for #408
takeGlobalQueue();
var map = makeModuleMap(id, null, true),
mod = registry[id];
delete defined[id];
delete urlFetched[map.url];
delete undefEvents[id];
if (mod) {
//Hold on to listeners in case the
//module will be attempted to be reloaded
//using a different config.
if (mod.events.defined) {
undefEvents[id] = mod.events;
}
removeWaiting(id);
}
},
/**
* Called to enable a module if it is still in the registry
* awaiting enablement. parent module is passed in for context,
* used by the optimizer.
*/
enable: function (depMap, parent) {
var mod = registry[depMap.id];
if (mod) {
getModule(depMap).enable();
}
},
/**
* Internal method used by environment adapters to complete a load event.
* A load event could be a script load or just a load pass from a synchronous
* load call.
* @param {String} moduleName the name of the module to potentially complete.
*/
completeLoad: function (moduleName) {
var found, args, mod,
shim = config.shim[moduleName] || {},
shExports = shim.exports && shim.exports.exports;
takeGlobalQueue();
while (defQueue.length) {
args = defQueue.shift();
if (args[0] === null) {
args[0] = moduleName;
//If already found an anonymous module and bound it
//to this name, then this is some other anon module
//waiting for its completeLoad to fire.
if (found) {
break;
}
found = true;
} else if (args[0] === moduleName) {
//Found matching define call for this script!
found = true;
}
callGetModule(args);
}
//Do this after the cycle of callGetModule in case the result
//of those calls/init calls changes the registry.
mod = registry[moduleName];
if (!found && !defined[moduleName] && mod && !mod.inited) {
if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
if (hasPathFallback(moduleName)) {
return;
} else {
return onError(makeError('nodefine',
'No define call for ' + moduleName,
null,
[moduleName]));
}
} else {
//A script that does not call define(), so just simulate
//the call for it.
callGetModule([moduleName, (shim.deps || []), shim.exports]);
}
}
checkLoaded();
},
/**
* Converts a module name + .extension into an URL path.
* *Requires* the use of a module name. It does not support using
* plain URLs like nameToUrl.
*/
toUrl: function (moduleNamePlusExt, relModuleMap) {
var index = moduleNamePlusExt.lastIndexOf('.'),
ext = null;
if (index !== -1) {
ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
}
return context.nameToUrl(normalize(moduleNamePlusExt, relModuleMap && relModuleMap.id, true),
ext);
},
/**
* Converts a module name to a file path. Supports cases where
* moduleName may actually be just an URL.
* Note that it **does not** call normalize on the moduleName,
* it is assumed to have already been normalized. This is an
* internal API, not a public one. Use toUrl for the public API.
*/
nameToUrl: function (moduleName, ext) {
var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
parentPath;
//If a colon is in the URL, it indicates a protocol is used and it is just
//an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
//or ends with .js, then assume the user meant to use an url and not a module id.
//The slash is important for protocol-less URLs as well as full paths.
if (req.jsExtRegExp.test(moduleName)) {
//Just a plain path, not module name lookup, so just return it.
//Add extension if it is included. This is a bit wonky, only non-.js things pass
//an extension, this method probably needs to be reworked.
url = moduleName + (ext || '');
} else {
//A module that needs to be converted to a path.
paths = config.paths;
pkgs = config.pkgs;
syms = moduleName.split('/');
//For each module name segment, see if there is a path
//registered for it. Start with most specific name
//and work up from it.
for (i = syms.length; i > 0; i -= 1) {
parentModule = syms.slice(0, i).join('/');
pkg = pkgs[parentModule];
parentPath = paths[parentModule];
if (parentPath) {
//If an array, it means there are a few choices,
//Choose the one that is desired
if (isArray(parentPath)) {
parentPath = parentPath[0];
}
syms.splice(0, i, parentPath);
break;
} else if (pkg) {
//If module name is just the package name, then looking
//for the main module.
if (moduleName === pkg.name) {
pkgPath = pkg.location + '/' + pkg.main;
} else {
pkgPath = pkg.location;
}
syms.splice(0, i, pkgPath);
break;
}
}
//Join the path parts together, then figure out if baseUrl is needed.
url = syms.join('/');
url += (ext || (/\?/.test(url) ? '' : '.js'));
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
}
return config.urlArgs ? url +
((url.indexOf('?') === -1 ? '?' : '&') +
config.urlArgs) : url;
},
//Delegates to req.load. Broken out as a separate function to
//allow overriding in the optimizer.
load: function (id, url) {
req.load(context, id, url);
},
/**
* Executes a module callack function. Broken out as a separate function
* solely to allow the build system to sequence the files in the built
* layer in the right sequence.
*
* @private
*/
execCb: function (name, callback, args, exports) {
return callback.apply(exports, args);
},
/**
* callback for script loads, used to check status of loading.
*
* @param {Event} evt the event from the browser for the script
* that was loaded.
*/
onScriptLoad: function (evt) {
//Using currentTarget instead of target for Firefox 2.0's sake. Not
//all old browsers will be supported, but this one was easy enough
//to support and still makes sense.
if (evt.type === 'load' ||
(readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
//Reset interactive script so a script node is not held onto for
//to long.
interactiveScript = null;
//Pull out the name of the module and the context.
var data = getScriptData(evt);
context.completeLoad(data.id);
}
},
/**
* Callback for script errors.
*/
onScriptError: function (evt) {
var data = getScriptData(evt);
if (!hasPathFallback(data.id)) {
return onError(makeError('scripterror', 'Script error', evt, [data.id]));
}
}
});
}
/**
* Main entry point.
*
* If the only argument to require is a string, then the module that
* is represented by that string is fetched for the appropriate context.
*
* If the first argument is an array, then it will be treated as an array
* of dependency string names to fetch. An optional function callback can
* be specified to execute when all of those dependencies are available.
*
* Make a local req variable to help Caja compliance (it assumes things
* on a require that are not standardized), and to give a short
* name for minification/local scope use.
*/
req = requirejs = function (deps, callback, errback, optional) {
//Find the right context, use default
var context, config,
contextName = defContextName;
// Determine if have config object in the call.
if (!isArray(deps) && typeof deps !== 'string') {
// deps is a config object
config = deps;
if (isArray(callback)) {
// Adjust args if there are dependencies
deps = callback;
callback = errback;
errback = optional;
} else {
deps = [];
}
}
if (config && config.context) {
contextName = config.context;
}
context = contexts[contextName];
if (!context) {
context = contexts[contextName] = req.s.newContext(contextName);
}
if (config) {
context.configure(config);
}
return context.require(deps, callback, errback);
};
/**
* Support require.config() to make it easier to cooperate with other
* AMD loaders on globally agreed names.
*/
req.config = function (config) {
return req(config);
};
/**
* Export require as a global, but only if it does not already exist.
*/
if (!require) {
require = req;
}
req.version = version;
//Used to filter out dependencies that are already paths.
req.jsExtRegExp = /^\/|:|\?|\.js$/;
req.isBrowser = isBrowser;
s = req.s = {
contexts: contexts,
newContext: newContext
};
//Create default context.
req({});
//Exports some context-sensitive methods on global require, using
//default context if no context specified.
addRequireMethods(req);
if (isBrowser) {
head = s.head = document.getElementsByTagName('head')[0];
//If BASE tag is in play, using appendChild is a problem for IE6.
//When that browser dies, this can be removed. Details in this jQuery bug:
//http://dev.jquery.com/ticket/2709
baseElement = document.getElementsByTagName('base')[0];
if (baseElement) {
head = s.head = baseElement.parentNode;
}
}
/**
* Any errors that require explicitly generates will be passed to this
* function. Intercept/override it if you want custom error handling.
* @param {Error} err the error object.
*/
req.onError = function (err) {
throw err;
};
/**
* Does the request to load a module for the browser case.
* Make this a separate function to allow other environments
* to override it.
*
* @param {Object} context the require context to find state.
* @param {String} moduleName the name of the module.
* @param {Object} url the URL to the module.
*/
req.load = function (context, moduleName, url) {
var config = (context && context.config) || {},
node;
if (isBrowser) {
//In the browser so use a script tag
node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
node.setAttribute('data-requirecontext', context.contextName);
node.setAttribute('data-requiremodule', moduleName);
//Set up load listener. Test attachEvent first because IE9 has
//a subtle issue in its addEventListener and script onload firings
//that do not match the behavior of all other browsers with
//addEventListener support, which fire the onload event for a
//script right after the script execution. See:
//https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
//UNFORTUNATELY Opera implements attachEvent but does not follow the script
//script execution mode.
if (node.attachEvent &&
//Check if node.attachEvent is artificially added by custom script or
//natively supported by browser
//read https://github.com/jrburke/requirejs/issues/187
//if we can NOT find [native code] then it must NOT natively supported.
//in IE8, node.attachEvent does not have toString()
//Note the test for "[native code" with no closing brace, see:
//https://github.com/jrburke/requirejs/issues/273
!(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
!isOpera) {
//Probably IE. IE (at least 6-8) do not fire
//script onload right after executing the script, so
//we cannot tie the anonymous define call to a name.
//However, IE reports the script as being in 'interactive'
//readyState at the time of the define call.
useInteractive = true;
node.attachEvent('onreadystatechange', context.onScriptLoad);
//It would be great to add an error handler here to catch
//404s in IE9+. However, onreadystatechange will fire before
//the error handler, so that does not help. If addEvenListener
//is used, then IE will fire error before load, but we cannot
//use that pathway given the connect.microsoft.com issue
//mentioned above about not doing the 'script execute,
//then fire the script load event listener before execute
//next script' that other browsers do.
//Best hope: IE10 fixes the issues,
//and then destroys all installs of IE 6-9.
//node.attachEvent('onerror', context.onScriptError);
} else {
node.addEventListener('load', context.onScriptLoad, false);
node.addEventListener('error', context.onScriptError, false);
}
node.src = url;
//For some cache cases in IE 6-8, the script executes before the end
//of the appendChild execution, so to tie an anonymous define
//call to the module name (which is stored on the node), hold on
//to a reference to this node, but clear after the DOM insertion.
currentlyAddingScript = node;
if (baseElement) {
head.insertBefore(node, baseElement);
} else {
head.appendChild(node);
}
currentlyAddingScript = null;
return node;
} else if (isWebWorker) {
//In a web worker, use importScripts. This is not a very
//efficient use of importScripts, importScripts will block until
//its script is downloaded and evaluated. However, if web workers
//are in play, the expectation that a build has been done so that
//only one script needs to be loaded anyway. This may need to be
//reevaluated if other use cases become common.
importScripts(url);
//Account for anonymous modules
context.completeLoad(moduleName);
}
};
function getInteractiveScript() {
if (interactiveScript && interactiveScript.readyState === 'interactive') {
return interactiveScript;
}
eachReverse(scripts(), function (script) {
if (script.readyState === 'interactive') {
return (interactiveScript = script);
}
});
return interactiveScript;
}
//Look for a data-main script attribute, which could also adjust the baseUrl.
if (isBrowser) {
//Figure out baseUrl. Get it from the script tag with require.js in it.
eachReverse(scripts(), function (script) {
//Set the 'head' where we can append children by
//using the script's parent.
if (!head) {
head = script.parentNode;
}
//Look for a data-main attribute to set main script for the page
//to load. If it is there, the path to data main becomes the
//baseUrl, if it is not already set.
dataMain = script.getAttribute('data-main');
if (dataMain) {
//Set final baseUrl if there is not already an explicit one.
if (!cfg.baseUrl) {
//Pull off the directory of data-main for use as the
//baseUrl.
src = dataMain.split('/');
mainScript = src.pop();
subPath = src.length ? src.join('/') + '/' : './';
cfg.baseUrl = subPath;
dataMain = mainScript;
}
//Strip off any trailing .js since dataMain is now
//like a module name.
dataMain = dataMain.replace(jsSuffixRegExp, '');
//Put the data-main script in the files to load.
cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain];
return true;
}
});
}
/**
* The function that handles definitions of modules. Differs from
* require() in that a string for the module should be the first argument,
* and the function to execute after dependencies are loaded should
* return a value to define the module corresponding to the first argument's
* name.
*/
define = function (name, deps, callback) {
var node, context;
//Allow for anonymous functions
if (typeof name !== 'string') {
//Adjust args appropriately
callback = deps;
deps = name;
name = null;
}
//This module may not have dependencies
if (!isArray(deps)) {
callback = deps;
deps = [];
}
//If no name, and callback is a function, then figure out if it a
//CommonJS thing with dependencies.
if (!deps.length && isFunction(callback)) {
//Remove comments from the callback string,
//look for require calls, and pull them into the dependencies,
//but only if there are function args.
if (callback.length) {
callback
.toString()
.replace(commentRegExp, '')
.replace(cjsRequireRegExp, function (match, dep) {
deps.push(dep);
});
//May be a CommonJS thing even without require calls, but still
//could use exports, and module. Avoid doing exports and module
//work though if it just needs require.
//REQUIRES the function to expect the CommonJS variables in the
//order listed below.
deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
}
}
//If in IE 6-8 and hit an anonymous define() call, do the interactive
//work.
if (useInteractive) {
node = currentlyAddingScript || getInteractiveScript();
if (node) {
if (!name) {
name = node.getAttribute('data-requiremodule');
}
context = contexts[node.getAttribute('data-requirecontext')];
}
}
//Always save off evaluating the def call until the script onload handler.
//This allows multiple modules to be in a file without prematurely
//tracing dependencies, and allows for anonymous module support,
//where the module name is not known until the script onload event
//occurs. If no context, use the global queue, and get it processed
//in the onscript load callback.
(context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
};
define.amd = {
jQuery: true
};
/**
* Executes the text. Normally just uses eval, but can be modified
* to use a better, environment-specific call. Only used for transpiling
* loader plugins, not for plain JS modules.
* @param {String} text the text to execute/evaluate.
*/
req.exec = function (text) {
/*jslint evil: true */
return eval(text);
};
//Set up with config info.
req(cfg);
}(this));
================================================
FILE: examples/requirejs/readme.md
================================================
================================================
FILE: examples/requirejs/require-example.html
================================================
RequireJS
================================================
FILE: examples/simpledatabinding/simpledatabinding.js
================================================
$(function () {
// Make a simple binding
var label1 = document.querySelector('#label1');
var hello = new Rx.BehaviorSubject('Hello');
hello.subscribe(function (text) {
label1.textContent = text;
});
// Create simple bindings for first and last name
var firstName1 = new Rx.BehaviorSubject('');
var lastName1 = new Rx.BehaviorSubject('');
// Create first and last name composite
var fullName1 = firstName1.combineLatest(lastName1, function (first, last) {
return first + ' ' + last;
});
// Subscribe to them all
var fn1 = document.querySelector('#firstName1');
firstName1.subscribe(function (text) { fn1.value = text });
var ln1 = document.querySelector('#lastName1');
lastName1.subscribe(function (text) { ln1.value = text });
var full1 = document.querySelector('#fullName1');
fullName1.subscribe(function (text) { full1.value = text });
// Create two way bindings for both first name and last name
Rx.Observable.fromEvent(fn1, 'keyup')
.subscribe(function (e) { firstName1.onNext(e.target.value); })
Rx.Observable.fromEvent(ln1, 'keyup')
.subscribe(function (e) { lastName1.onNext(e.target.value); })
});
================================================
FILE: examples/speech/readme.md
================================================
================================================
FILE: examples/speech/speech.html
================================================
Rx for JavaScript Rocks!
RxJS Speech Detection Example
Example to show combining speech recognition and sythesis using RxJS
";
}
}
runLoggingCallbacks( "log", QUnit, details );
config.current.assertions.push({
result: result,
message: msg
});
},
/**
* Assert that the first two arguments are equal, with an optional message.
* Prints out both actual and expected values.
* @name equal
* @function
* @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
*/
equal: function( actual, expected, message ) {
QUnit.push( expected == actual, actual, expected, message );
},
/**
* @name notEqual
* @function
*/
notEqual: function( actual, expected, message ) {
QUnit.push( expected != actual, actual, expected, message );
},
/**
* @name deepEqual
* @function
*/
deepEqual: function( actual, expected, message ) {
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
},
/**
* @name notDeepEqual
* @function
*/
notDeepEqual: function( actual, expected, message ) {
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
},
/**
* @name strictEqual
* @function
*/
strictEqual: function( actual, expected, message ) {
QUnit.push( expected === actual, actual, expected, message );
},
/**
* @name notStrictEqual
* @function
*/
notStrictEqual: function( actual, expected, message ) {
QUnit.push( expected !== actual, actual, expected, message );
},
throws: function( block, expected, message ) {
var actual,
ok = false;
// 'expected' is optional
if ( typeof expected === "string" ) {
message = expected;
expected = null;
}
config.current.ignoreGlobalErrors = true;
try {
block.call( config.current.testEnvironment );
} catch (e) {
actual = e;
}
config.current.ignoreGlobalErrors = false;
if ( actual ) {
// we don't want to validate thrown error
if ( !expected ) {
ok = true;
// expected is a regexp
} else if ( QUnit.objectType( expected ) === "regexp" ) {
ok = expected.test( actual );
// expected is a constructor
} else if ( actual instanceof expected ) {
ok = true;
// expected is a validation function which returns true is validation passed
} else if ( expected.call( {}, actual ) === true ) {
ok = true;
}
QUnit.push( ok, actual, null, message );
} else {
QUnit.pushFailure( message, null, 'No exception was thrown.' );
}
}
};
/**
* @deprecate since 1.8.0
* Kept assertion helpers in root for backwards compatibility
*/
extend( QUnit, QUnit.assert );
/**
* @deprecated since 1.9.0
* Kept global "raises()" for backwards compatibility
*/
QUnit.raises = QUnit.assert.throws;
/**
* @deprecated since 1.0.0, replaced with error pushes since 1.3.0
* Kept to avoid TypeErrors for undefined methods.
*/
QUnit.equals = function() {
QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
};
QUnit.same = function() {
QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
};
// We want access to the constructor's prototype
(function() {
function F() {}
F.prototype = QUnit;
QUnit = new F();
// Make F QUnit's constructor so that we can add to the prototype later
QUnit.constructor = F;
}());
/**
* Config object: Maintain internal state
* Later exposed as QUnit.config
* `config` initialized at top of scope
*/
config = {
// The queue of tests to run
queue: [],
// block until document ready
blocking: true,
// when enabled, show only failing tests
// gets persisted through sessionStorage and can be changed in UI via checkbox
hidepassed: false,
// by default, run previously failed tests first
// very useful in combination with "Hide passed tests" checked
reorder: true,
// by default, modify document.title when suite is done
altertitle: true,
// when enabled, all tests must call expect()
requireExpects: false,
// add checkboxes that are persisted in the query-string
// when enabled, the id is set to `true` as a `QUnit.config` property
urlConfig: [
{
id: "noglobals",
label: "Check for Globals",
tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
},
{
id: "notrycatch",
label: "No try-catch",
tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
}
],
// Set of all modules.
modules: {},
// logging callback queues
begin: [],
done: [],
log: [],
testStart: [],
testDone: [],
moduleStart: [],
moduleDone: []
};
// Initialize more QUnit.config and QUnit.urlParams
(function() {
var i,
location = window.location || { search: "", protocol: "file:" },
params = location.search.slice( 1 ).split( "&" ),
length = params.length,
urlParams = {},
current;
if ( params[ 0 ] ) {
for ( i = 0; i < length; i++ ) {
current = params[ i ].split( "=" );
current[ 0 ] = decodeURIComponent( current[ 0 ] );
// allow just a key to turn on a flag, e.g., test.html?noglobals
current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
urlParams[ current[ 0 ] ] = current[ 1 ];
}
}
QUnit.urlParams = urlParams;
// String search anywhere in moduleName+testName
config.filter = urlParams.filter;
// Exact match of the module name
config.module = urlParams.module;
config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
// Figure out if we're running the tests from a server or not
QUnit.isLocal = location.protocol === "file:";
}());
// Export global variables, unless an 'exports' object exists,
// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
if ( typeof exports === "undefined" ) {
extend( window, QUnit );
// Expose QUnit object
window.QUnit = QUnit;
}
// Extend QUnit object,
// these after set here because they should not be exposed as global functions
extend( QUnit, {
config: config,
// Initialize the configuration options
init: function() {
extend( config, {
stats: { all: 0, bad: 0 },
moduleStats: { all: 0, bad: 0 },
started: +new Date(),
updateRate: 1000,
blocking: false,
autostart: true,
autorun: false,
filter: "",
queue: [],
semaphore: 0
});
var tests, banner, result,
qunit = id( "qunit" );
if ( qunit ) {
qunit.innerHTML =
"
" + escapeInnerText( document.title ) + "
" +
"" +
"" +
"" +
"";
}
tests = id( "qunit-tests" );
banner = id( "qunit-banner" );
result = id( "qunit-testresult" );
if ( tests ) {
tests.innerHTML = "";
}
if ( banner ) {
banner.className = "";
}
if ( result ) {
result.parentNode.removeChild( result );
}
if ( tests ) {
result = document.createElement( "p" );
result.id = "qunit-testresult";
result.className = "result";
tests.parentNode.insertBefore( result, tests );
result.innerHTML = "Running... ";
}
},
// Resets the test setup. Useful for tests that modify the DOM.
reset: function() {
var fixture = id( "qunit-fixture" );
if ( fixture ) {
fixture.innerHTML = config.fixture;
}
},
// Trigger an event on an element.
// @example triggerEvent( document.body, "click" );
triggerEvent: function( elem, type, event ) {
if ( document.createEvent ) {
event = document.createEvent( "MouseEvents" );
event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
elem.dispatchEvent( event );
} else if ( elem.fireEvent ) {
elem.fireEvent( "on" + type );
}
},
// Safe object type checking
is: function( type, obj ) {
return QUnit.objectType( obj ) == type;
},
objectType: function( obj ) {
if ( typeof obj === "undefined" ) {
return "undefined";
// consider: typeof null === object
}
if ( obj === null ) {
return "null";
}
var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || "";
switch ( type ) {
case "Number":
if ( isNaN(obj) ) {
return "nan";
}
return "number";
case "String":
case "Boolean":
case "Array":
case "Date":
case "RegExp":
case "Function":
return type.toLowerCase();
}
if ( typeof obj === "object" ) {
return "object";
}
return undefined;
},
push: function( result, actual, expected, message ) {
if ( !config.current ) {
throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
}
var output, source,
details = {
module: config.current.module,
name: config.current.testName,
result: result,
message: message,
actual: actual,
expected: expected
};
message = escapeInnerText( message ) || ( result ? "okay" : "failed" );
message = "" + message + "";
output = message;
if ( !result ) {
expected = escapeInnerText( QUnit.jsDump.parse(expected) );
actual = escapeInnerText( QUnit.jsDump.parse(actual) );
output += "
O(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+O(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+O(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+O(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+O(f,h).toFixed(2)))return{x:l,y:m}}}}function m(a,b,d){var e=c.bezierBBox(a),f=c.bezierBBox(b);if(!c.isBBoxIntersect(e,f))return d?0:[];for(var g=j.apply(0,a),h=j.apply(0,b),i=O(~~(g/5),1),k=O(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;i+1>q;q++){var r=c.findDotsAtSegment.apply(c,a.concat(q/i));m.push({x:r.x,y:r.y,t:q/i})}for(q=0;k+1>q;q++)r=c.findDotsAtSegment.apply(c,b.concat(q/k)),n.push({x:r.x,y:r.y,t:q/k});for(q=0;i>q;q++)for(var s=0;k>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=Q(u.x-t.x)<.001?"y":"x",y=Q(w.x-v.x)<.001?"y":"x",z=l(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4))continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+Q((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+Q((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:P(A,1),t2:P(B,1)}))}}return p}function n(a,b,d){a=c._path2curve(a),b=c._path2curve(b);for(var e,f,g,h,i,j,k,l,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0])e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=b.length;u>t;t++){var v=b[t];if("M"==v[0])g=k=v[1],h=l=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,l,k,l],g=k,h=l);var w=m(n,o,d);if(d)p+=w;else{for(var x=0,y=w.length;y>x;x++)w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}}return p}function o(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function p(){return this.x+H+this.y+H+this.width+" × "+this.height}function q(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a}function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c}function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,Q(f)e)return c;if(e>d)return d;for(;d>c;){if(f=g(e),Q(f-a)f?c=e:d=e,e=(d-c)/2+c}return e}var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))}function r(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a)a[z](e)&&(d[_(e)]=a[e],c.push(_(e)));c.sort(lb)}this.anim=d,this.top=c[c.length-1],this.percents=c}function s(a,d,e,f,g,h){e=_(e);var i,j,k,l,m,n,p=a.ms,r={},s={},t={};if(f)for(v=0,x=ic.length;x>v;v++){var u=ic[v];if(u.el.id==d.id&&u.anim==a){u.percent!=e?(ic.splice(v,1),k=1):j=u,d.attr(u.totalOrigin);break}}else f=+s;for(var v=0,x=a.percents.length;x>v;v++){if(a.percents[v]==e||a.percents[v]>f*a.top){e=a.percents[v],m=a.percents[v-1]||0,p=p/a.top*(e-m),l=a.percents[v+1],i=a.anim[e];break}f&&d.attr(a.anim[a.percents[v]])}if(i){if(j)j.initstatus=f,j.start=new Date-j.ms*f;else{for(var y in i)if(i[z](y)&&(db[z](y)||d.paper.customAttributes[z](y)))switch(r[y]=d.attr(y),null==r[y]&&(r[y]=cb[y]),s[y]=i[y],db[y]){case T:t[y]=(s[y]-r[y])/p;break;case"colour":r[y]=c.getRGB(r[y]);var A=c.getRGB(s[y]);t[y]={r:(A.r-r[y].r)/p,g:(A.g-r[y].g)/p,b:(A.b-r[y].b)/p};break;case"path":var B=Kb(r[y],s[y]),C=B[1];for(r[y]=B[0],t[y]=[],v=0,x=r[y].length;x>v;v++){t[y][v]=[0];for(var D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(C[v][D]-r[y][v][D])/p}break;case"transform":var G=d._,H=Pb(G[y],s[y]);if(H)for(r[y]=H.from,s[y]=H.to,t[y]=[],t[y].real=!0,v=0,x=r[y].length;x>v;v++)for(t[y][v]=[r[y][v][0]],D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(s[y][v][D]-r[y][v][D])/p;else{var K=d.matrix||new o,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[y]=[K.a,K.b,K.c,K.d,K.e,K.f],Nb(L,s[y]),s[y]=L._.transform,t[y]=[(L.matrix.a-K.a)/p,(L.matrix.b-K.b)/p,(L.matrix.c-K.c)/p,(L.matrix.d-K.d)/p,(L.matrix.e-K.e)/p,(L.matrix.f-K.f)/p]}break;case"csv":var M=I(i[y])[J](w),N=I(r[y])[J](w);if("clip-rect"==y)for(r[y]=N,t[y]=[],v=N.length;v--;)t[y][v]=(M[v]-r[y][v])/p;s[y]=M;break;default:for(M=[][E](i[y]),N=[][E](r[y]),t[y]=[],v=d.paper.customAttributes[y].length;v--;)t[y][v]=((M[v]||0)-(N[v]||0))/p}var O=i.easing,P=c.easing_formulas[O];if(!P)if(P=I(O).match(Z),P&&5==P.length){var Q=P;P=function(a){return q(a,+Q[1],+Q[2],+Q[3],+Q[4],p)}}else P=nb;if(n=i.start||a.start||+new Date,u={anim:a,percent:e,timestamp:n,start:n+(a.del||0),status:0,initstatus:f||0,stop:!1,ms:p,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||a.times,origin:d.attr(),totalOrigin:g},ic.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-p*f,1==ic.length))return kc();k&&(u.start=new Date-u.ms*f),1==ic.length&&jc(kc)}b("raphael.anim.start."+d.id,d,a)}}function t(a){for(var b=0;be;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(c._g=A,c.type=A.win.SVGAngle||A.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==c.type){var sb,tb=A.doc.createElement("div");if(tb.innerHTML='',sb=tb.firstChild,sb.style.behavior="url(#default#VML)",!sb||"object"!=typeof sb.adj)return c.type=G;tb=null}c.svg=!(c.vml="VML"==c.type),c._Paper=C,c.fn=v=C.prototype=c.prototype,c._id=0,c._oid=0,c.is=function(a,b){return b=M.call(b),"finite"==b?!Y[z](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||W.call(a).slice(8,-1).toLowerCase()==b},c.angle=function(a,b,d,e,f,g){if(null==f){var h=a-d,i=b-e;return h||i?(180+180*N.atan2(-i,-h)/S+360)%360:0}return c.angle(a,b,f,g)-c.angle(d,e,f,g)},c.rad=function(a){return a%360*S/180},c.deg=function(a){return 180*a/S%360},c.snapTo=function(a,b,d){if(d=c.is(d,"finite")?d:10,c.is(a,V)){for(var e=a.length;e--;)if(Q(a[e]-b)<=d)return a[e]}else{a=+a;var f=b%a;if(d>f)return b-f;if(f>a-d)return b-f+a}return b};c.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=16*N.random()|0,c="x"==a?b:3&b|8;return c.toString(16)});c.setWindow=function(a){b("raphael.setWindow",c,A.win,a),A.win=a,A.doc=A.win.document,c._engine.initWin&&c._engine.initWin(A.win)};var ub=function(a){if(c.vml){var b,d=/^\s+|\s+$/g;try{var e=new ActiveXObject("htmlfile");e.write(""),e.close(),b=e.body}catch(g){b=createPopup().document.body}var h=b.createTextRange();ub=f(function(a){try{b.style.color=I(a).replace(d,G);var c=h.queryCommandValue("ForeColor");return c=(255&c)<<16|65280&c|(16711680&c)>>>16,"#"+("000000"+c.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=A.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",A.doc.body.appendChild(i),ub=f(function(a){return i.style.color=a,A.doc.defaultView.getComputedStyle(i,G).getPropertyValue("color")})}return ub(a)},vb=function(){return"hsb("+[this.h,this.s,this.b]+")"},wb=function(){return"hsl("+[this.h,this.s,this.l]+")"},xb=function(){return this.hex},yb=function(a,b,d){if(null==b&&c.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&c.is(a,U)){var e=c.getRGB(a);a=e.r,b=e.g,d=e.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},zb=function(a,b,d,e){a*=255,b*=255,d*=255;var f={r:a,g:b,b:d,hex:c.rgb(a,b,d),toString:xb};return c.is(e,"finite")&&(f.opacity=e),f};c.color=function(a){var b;return c.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):c.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):(c.is(a,"string")&&(a=c.getRGB(a)),c.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=xb,a},c.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-Q(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-Q(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.rgb2hsb=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=O(a,b,c),g=f-P(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:vb}},c.rgb2hsl=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=O(a,b,c),h=P(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:wb}},c._path2string=function(){return this.join(",").replace(gb,"$1")};c._preload=function(a,b){var c=A.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,A.doc.body.removeChild(this)},c.onerror=function(){A.doc.body.removeChild(this)},A.doc.body.appendChild(c),c.src=a};c.getRGB=f(function(a){if(!a||(a=I(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:g};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:g};!(fb[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=ub(a));var b,d,e,f,h,i,j=a.match(X);return j?(j[2]&&(e=ab(j[2].substring(5),16),d=ab(j[2].substring(3,5),16),b=ab(j[2].substring(1,3),16)),j[3]&&(e=ab((h=j[3].charAt(3))+h,16),d=ab((h=j[3].charAt(2))+h,16),b=ab((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100)),j[5]?(i=j[5][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100),c.hsb2rgb(b,d,e,f)):j[6]?(i=j[6][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100),c.hsl2rgb(b,d,e,f)):(j={r:b,g:d,b:e,toString:g},j.hex="#"+(16777216|e|d<<8|b<<16).toString(16).slice(1),c.is(f,"finite")&&(j.opacity=f),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:g}},c),c.hsb=f(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=f(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=f(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),c.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},c.getColor.reset=function(){delete this.start},c.parsePathString=function(a){if(!a)return null;var b=Ab(a);if(b.arr)return Cb(b.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return c.is(a,V)&&c.is(a[0],V)&&(e=Cb(a)),e.length||I(a).replace(hb,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(jb,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][E](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g)e.push([b][E](f));else for(;f.length>=d[g]&&(e.push([b][E](f.splice(0,d[g]))),d[g]););}),e.toString=c._path2string,b.arr=Cb(e),e},c.parseTransformString=f(function(a){if(!a)return null;var b=[];return c.is(a,V)&&c.is(a[0],V)&&(b=Cb(a)),b.length||I(a).replace(ib,function(a,c,d){{var e=[];M.call(c)}d.replace(jb,function(a,b){b&&e.push(+b)}),b.push([c][E](e))}),b.toString=c._path2string,b});var Ab=function(a){var b=Ab.ps=Ab.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[z](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};c.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/S;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},c.bezierBBox=function(a,b,d,e,f,g,h,i){c.is(a,"array")||(a=[a,b,d,e,f,g,h,i]);var j=Jb.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},c.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},c.isBBoxIntersect=function(a,b){var d=c.isPointInsideBBox;return d(b,a.x,a.y)||d(b,a.x2,a.y)||d(b,a.x,a.y2)||d(b,a.x2,a.y2)||d(a,b.x,b.y)||d(a,b.x2,b.y)||d(a,b.x,b.y2)||d(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)},c.pathIntersection=function(a,b){return n(a,b)},c.pathIntersectionNumber=function(a,b){return n(a,b,1)},c.isPointInsidePath=function(a,b,d){var e=c.pathBBox(a);return c.isPointInsideBBox(e,b,d)&&n(a,[["M",b,d],["H",e.x2+10]],1)%2==1},c._removedFactory=function(a){return function(){b("raphael.log",null,"Raphaël: you are calling to method “"+a+"” of removed object",a)}};var Bb=c.pathBBox=function(a){var b=Ab(a);if(b.bbox)return d(b.bbox);if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Kb(a);for(var c,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++)if(c=a[i],"M"==c[0])e=c[1],f=c[2],g.push(e),h.push(f);else{var k=Jb(e,f,c[1],c[2],c[3],c[4],c[5],c[6]);g=g[E](k.min.x,k.max.x),h=h[E](k.min.y,k.max.y),e=c[5],f=c[6]}var l=P[D](0,g),m=P[D](0,h),n=O[D](0,g),o=O[D](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=d(r),r},Cb=function(a){var b=d(a);return b.toString=c._path2string,b},Db=c._pathToRelative=function(a){var b=Ab(a);if(b.rel)return Cb(b.rel);c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=M.call(m[0]))switch(l[0]=M.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}return d.toString=c._path2string,b.rel=Cb(d),d},Eb=c._pathToAbsolute=function(a){var b=Ab(a);if(b.abs)return Cb(b.abs);if(c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a)),!a||!a.length)return[["M",0,0]];var d=[],e=0,f=0,g=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],g=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=bb.call(l[0]))switch(k[0]=bb.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][E](l.slice(1)),q=2,r=p.length;r>q;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[E](h(p,m));break;case"M":g=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++)k[q]=+l[q]+(q%2?e:f)}else if("R"==l[0])p=[e,f][E](l.slice(1)),d.pop(),d=d[E](h(p,m)),k=["R"][E](l.slice(-2));else for(var s=0,t=l.length;t>s;s++)k[s]=l[s];switch(k[0]){case"Z":e=g,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":g=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}return d.toString=c._path2string,b.abs=Cb(d),d},Fb=function(a,b,c,d){return[a,b,c,d,c,d]},Gb=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Hb=function(a,b,c,d,e,g,h,i,j,k){var l,m=120*S/180,n=S/180*(+e||0),o=[],p=f(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(S/180*e),N.sin(S/180*e),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=N.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*N.sqrt(Q((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v*-d*q/c+(b+j)/2,y=N.asin(((b-x)/d).toFixed(9)),z=N.asin(((j-x)/d).toFixed(9));y=w>a?S-y:y,z=w>i?S-z:z,0>y&&(y=2*S+y),0>z&&(z=2*S+z),h&&y>z&&(y-=2*S),!h&&z>y&&(z-=2*S)}var A=z-y;if(Q(A)>m){var B=z,C=i,D=j;z=y+m*(h&&z>y?1:-1),i=w+c*N.cos(z),j=x+d*N.sin(z),o=Hb(i,j,c,d,e,0,h,C,D,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),K=N.tan(A/4),L=4/3*c*K,M=4/3*d*K,O=[a,b],P=[a+L*G,b-M*F],R=[i+L*I,j-M*H],T=[i,j];if(P[0]=2*O[0]-P[0],P[1]=2*O[1]-P[1],k)return[P,R,T][E](o);o=[P,R,T][E](o).join()[J](",");for(var U=[],V=0,W=o.length;W>V;V++)U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ib=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:R(j,3)*a+3*R(j,2)*i*c+3*j*i*i*e+R(i,3)*g,y:R(j,3)*b+3*R(j,2)*i*d+3*j*i*i*f+R(i,3)*h}},Jb=f(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return Q(m)>"1e12"&&(m=.5),Q(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,Q(m)>"1e12"&&(m=.5),Q(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:P[D](0,p),y:P[D](0,o)},max:{x:O[D](0,p),y:O[D](0,o)}}}),Kb=c._path2curve=f(function(a,b){var c=!b&&Ab(a);if(!b&&c.curve)return Cb(c.curve);for(var d=Eb(a),e=b&&Eb(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e,f={T:1,Q:1};if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in f)&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][E](Hb[D](0,[b.x,b.y][E](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][E](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][E](Gb(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][E](Gb(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][E](Fb(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][E](Fb(b.x,b.y,a[1],b.y));break;case"V":a=["C"][E](Fb(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][E](Fb(b.x,b.y,b.X,b.Y))}return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)a.splice(b++,0,["C"][E](c.splice(0,6)));a.splice(b,1),l=O(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],l=O(d.length,e&&e.length||0))},k=0,l=O(d.length,e&&e.length||0);l>k;k++){d[k]=h(d[k],f),i(d,k),e&&(e[k]=h(e[k],g)),e&&i(e,k),j(d,e,f,g,k),j(e,d,g,f,k);var m=d[k],n=e&&e[k],o=m.length,p=e&&n.length;f.x=m[o-2],f.y=m[o-1],f.bx=_(m[o-4])||f.x,f.by=_(m[o-3])||f.y,g.bx=e&&(_(n[p-4])||g.x),g.by=e&&(_(n[p-3])||g.y),g.x=e&&n[p-2],g.y=e&&n[p-1]}return e||(c.curve=Cb(d)),e?[d,e]:d},null,Cb),Lb=(c._parseDots=f(function(a){for(var b=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=c.getRGB(g[1]),f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),b.push(f)}for(d=1,e=b.length-1;e>d;d++)if(!b[d].offset){for(var h=_(b[d-1].offset||0),i=0,j=d+1;e>j;j++)if(b[j].offset){i=b[j].offset;break}i||(i=100,j=e),i=_(i);for(var k=(i-h)/(j-d+1);j>d;d++)h+=k,b[d].offset=h+"%"}return b}),c._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Mb=(c._tofront=function(a,b){b.top!==a&&(Lb(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},c._toback=function(a,b){b.bottom!==a&&(Lb(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},c._insertafter=function(a,b,c){Lb(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},c._insertbefore=function(a,b,c){Lb(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},c.toMatrix=function(a,b){var c=Bb(a),d={_:{transform:G},getBBox:function(){return c}};return Nb(d,b),d.matrix}),Nb=(c.transformPath=function(a,b){return rb(a,Mb(a,b))},c._extractTransform=function(a,b){if(null==b)return a._.transform;b=I(b).replace(/\.{3}|\u2026/g,a._.transform||G);var d=c.parseTransformString(b),e=0,f=0,g=0,h=1,i=1,j=a._,k=new o;if(j.transform=d||[],d)for(var l=0,m=d.length;m>l;l++){var n,p,q,r,s,t=d[l],u=t.length,v=I(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(n=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-n,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k}a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ob=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Pb=c._equaliseTransform=function(a,b){b=I(b).replace(/\.{3}|\u2026/g,a),a=c.parseTransformString(a)||[],b=c.parseTransformString(b)||[];for(var d,e,f,g,h=O(a.length,b.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ob(b[k]),g=b[k]||Ob(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4]))return;for(i[k]=[],j[k]=[],d=0,e=O(f.length,g.length);e>d;d++)d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])
}return{from:i,to:j}};c._getContainer=function(a,b,d,e){var f;return f=null!=e||c.is(a,"object")?a:A.doc.getElementById(a),null!=f?f.tagName?null==b?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:b,height:d}:{container:1,x:a,y:b,width:d,height:e}:void 0},c.pathToRelative=Db,c._engine={},c.path2curve=Kb,c.matrix=function(a,b,c,d,e,f){return new o(a,b,c,d,e,f)},function(a){function b(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var c=N.sqrt(b(a));a[0]&&(a[0]/=c),a[1]&&(a[1]/=c)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof o&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new o(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new o(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,b,d){a=c.rad(a),b=b||0,d=d||0;var e=+N.cos(a).toFixed(9),f=+N.sin(a).toFixed(9);this.add(e,f,-f,e,b,d),this.add(1,0,0,1,-b,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[I.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return c.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=N.sqrt(b(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=N.sqrt(b(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=c.deg(N.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=c.deg(N.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[J]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:G)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:G)+(b.rotate?"r"+[b.rotate,0,0]:G)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(o.prototype);var Qb=navigator.userAgent.match(/Version\/(.*?)\s/)||navigator.userAgent.match(/Chrome\/(\d+)/);v.safari="Apple Computer, Inc."==navigator.vendor&&(Qb&&Qb[1]<4||"iP"==navigator.platform.slice(0,2))||"Google Inc."==navigator.vendor&&Qb&&Qb[1]<8?function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});setTimeout(function(){a.remove()})}:mb;for(var Rb=function(){this.returnValue=!1},Sb=function(){return this.originalEvent.preventDefault()},Tb=function(){this.cancelBubble=!0},Ub=function(){return this.originalEvent.stopPropagation()},Vb=function(a){var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,c=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Wb=function(){return A.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Vb(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),F&&L[b]){var f=function(b){for(var e=Vb(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++)if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Sb,b.stopPropagation=Ub;break}return c.call(d,b,e.x,e.y)};a.addEventListener(L[b],f,!1)}return function(){return a.removeEventListener(b,e,!1),F&&L[b]&&a.removeEventListener(L[b],e,!1),!0}}:A.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||A.win.event;var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,e=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Rb,a.stopPropagation=a.stopPropagation||Tb,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0}(),Xb=[],Yb=function(a){for(var c,d=a.clientX,e=a.clientY,f=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,g=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,h=Xb.length;h--;){if(c=Xb[h],F&&a.touches){for(var i,j=a.touches.length;j--;)if(i=a.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;A.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,A.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&b("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,b("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},Zb=function(a){c.unmousemove(Yb).unmouseup(Zb);for(var d,e=Xb.length;e--;)d=Xb[e],d.el._drag={},b("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,a);Xb=[]},$b=c.el={},_b=K.length;_b--;)!function(a){c[a]=$b[a]=function(b,d){return c.is(b,"function")&&(this.events=this.events||[],this.events.push({name:a,f:b,unbind:Wb(this.shape||this.node||A.doc,a,b,d||this)})),this},c["un"+a]=$b["un"+a]=function(b){for(var d=this.events||[],e=d.length;e--;)d[e].name!=a||!c.is(b,"undefined")&&d[e].f!=b||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}}(K[_b]);$b.data=function(a,d){var e=kb[this.id]=kb[this.id]||{};if(0==arguments.length)return e;if(1==arguments.length){if(c.is(a,"object")){for(var f in a)a[z](f)&&this.data(f,a[f]);return this}return b("raphael.data.get."+this.id,this,e[a],a),e[a]}return e[a]=d,b("raphael.data.set."+this.id,this,d,a),this},$b.removeData=function(a){return null==a?kb[this.id]={}:kb[this.id]&&delete kb[this.id][a],this},$b.getData=function(){return d(kb[this.id]||{})},$b.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},$b.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var ac=[];$b.drag=function(a,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,m=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;if(this._drag.id=i.identifier,F&&i.touches)for(var n,o=i.touches.length;o--;)if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break}this._drag.x=j+m,this._drag.y=k+l,!Xb.length&&c.mousemove(Yb).mouseup(Zb),Xb.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("raphael.drag.start."+this.id,d),a&&b.on("raphael.drag.move."+this.id,a),e&&b.on("raphael.drag.end."+this.id,e),b("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)}return this._drag={},ac.push({el:this,start:i}),this.mousedown(i),this},$b.onDragOver=function(a){a?b.on("raphael.drag.over."+this.id,a):b.unbind("raphael.drag.over."+this.id)},$b.undrag=function(){for(var a=ac.length;a--;)ac[a].el==this&&(this.unmousedown(ac[a].start),ac.splice(a,1),b.unbind("raphael.drag.*."+this.id));!ac.length&&c.unmousemove(Yb).unmouseup(Zb),Xb=[]},v.circle=function(a,b,d){var e=c._engine.circle(this,a||0,b||0,d||0);return this.__set__&&this.__set__.push(e),e},v.rect=function(a,b,d,e,f){var g=c._engine.rect(this,a||0,b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.ellipse=function(a,b,d,e){var f=c._engine.ellipse(this,a||0,b||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},v.path=function(a){a&&!c.is(a,U)&&!c.is(a[0],V)&&(a+=G);var b=c._engine.path(c.format[D](c,arguments),this);return this.__set__&&this.__set__.push(b),b},v.image=function(a,b,d,e,f){var g=c._engine.image(this,a||"about:blank",b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.text=function(a,b,d){var e=c._engine.text(this,a||0,b||0,I(d));return this.__set__&&this.__set__.push(e),e},v.set=function(a){!c.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var b=new mc(a);return this.__set__&&this.__set__.push(b),b.paper=this,b.type="set",b},v.setStart=function(a){this.__set__=a||this.set()},v.setFinish=function(){var a=this.__set__;return delete this.__set__,a},v.setSize=function(a,b){return c._engine.setSize.call(this,a,b)},v.setViewBox=function(a,b,d,e,f){return c._engine.setViewBox.call(this,a,b,d,e,f)},v.top=v.bottom=null,v.raphael=c;var bc=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(A.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(A.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};v.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=A.doc.elementFromPoint(a,b);if(A.win.opera&&"svg"==e.tagName){var f=bc(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])}if(!e)return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;)e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},v.getElementsByBBox=function(a){var b=this.set();return this.forEach(function(d){c.isBBoxIntersect(d.getBBox(),a)&&b.push(d)}),b},v.getById=function(a){for(var b=this.bottom;b;){if(b.id==a)return b;b=b.next}return null},v.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1)return this;c=c.next}return this},v.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},$b.isPointInside=function(a,b){var d=this.realPath=qb[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=c.transformPath(d,this.attr("transform"))),c.isPointInsidePath(d,a,b)},$b.getBBox=function(a){if(this.removed)return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=qb[this.type](this),b.bboxwt=Bb(this.realPath),b.bboxwt.toString=p,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=qb[this.type](this)),b.bbox=Bb(rb(this.realPath,this.matrix)),b.bbox.toString=p,b.dirty=b.dirtyT=0),b.bbox)},$b.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},$b.glow=function(a){if("text"==this.type)return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||qb[this.type](this);f=this.matrix?rb(f,this.matrix):f;for(var g=1;c+1>g;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var cc=function(a,b,d,e,f,g,h,i,l){return null==l?j(a,b,d,e,f,g,h,i):c.findDotsAtSegment(a,b,d,e,f,g,h,i,k(a,b,d,e,f,g,h,i,l))},dc=function(a,b){return function(d,e,f){d=Kb(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0])g=+i[1],h=+i[2];else{if(j=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(b&&!m.start){if(k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f)return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!a&&!b)return k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}}n+=j,g=+i[5],h=+i[6]}l+=i.shift()+i}return m.end=l,k=a?n:b?m:c.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},ec=dc(1),fc=dc(),gc=dc(0,1);c.getTotalLength=ec,c.getPointAtLength=fc,c.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return gc(a,b).end;var d=gc(a,c,1);return b?gc(d,b).end:d},$b.getTotalLength=function(){var a=this.getPath();if(a)return this.node.getTotalLength?this.node.getTotalLength():ec(a)},$b.getPointAtLength=function(a){var b=this.getPath();if(b)return fc(b,a)},$b.getPath=function(){var a,b=c._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return b&&(a=b(this)),a},$b.getSubpath=function(a,b){var d=this.getPath();if(d)return c.getSubpath(d,a,b)};var hc=c.easing_formulas={linear:function(a){return a},"<":function(a){return R(a,1.7)},">":function(a){return R(a,.48)},"<>":function(a){var b=.48-a/1.04,c=N.sqrt(.1734+b*b),d=c-b,e=R(Q(d),1/3)*(0>d?-1:1),f=-c-b,g=R(Q(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:R(2,-10*a)*N.sin(2*(a-.075)*S/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};hc.easeIn=hc["ease-in"]=hc["<"],hc.easeOut=hc["ease-out"]=hc[">"],hc.easeInOut=hc["ease-in-out"]=hc["<>"],hc["back-in"]=hc.backIn,hc["back-out"]=hc.backOut;var ic=[],jc=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},kc=function(){for(var a=+new Date,d=0;dh))if(i>h){var q=j(h/i);for(var r in k)if(k[z](r)){switch(db[r]){case T:f=+k[r]+q*i*l[r];break;case"colour":f="rgb("+[lc($(k[r].r+q*i*l[r].r)),lc($(k[r].g+q*i*l[r].g)),lc($(k[r].b+q*i*l[r].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[r].length;u>t;t++){f[t]=[k[r][t][0]];for(var v=1,w=k[r][t].length;w>v;v++)f[t][v]=+k[r][t][v]+q*i*l[r][t][v];f[t]=f[t].join(H)}f=f.join(H);break;case"transform":if(l[r].real)for(f=[],t=0,u=k[r].length;u>t;t++)for(f[t]=[k[r][t][0]],v=1,w=k[r][t].length;w>v;v++)f[t][v]=k[r][t][v]+q*i*l[r][t][v];else{var x=function(a){return+k[r][a]+q*i*l[r][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]}break;case"csv":if("clip-rect"==r)for(f=[],t=4;t--;)f[t]=+k[r][t]+q*i*l[r][t];break;default:var y=[][E](k[r]);for(f=[],t=n.paper.customAttributes[r].length;t--;)f[t]=+y[t]+q*i*l[r][t]}o[r]=f}n.attr(o),function(a,c,d){setTimeout(function(){b("raphael.anim.frame."+a,c,d)})}(n.id,n,e.anim)}else{if(function(a,d,e){setTimeout(function(){b("raphael.anim.frame."+d.id,d,e),b("raphael.anim.finish."+d.id,d,e),c.is(a,"function")&&a.call(d)})}(e.callback,n,e.anim),n.attr(m),ic.splice(d--,1),e.repeat>1&&!e.next){for(g in m)m[z](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),s(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)}e.next&&!e.stop&&s(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}}c.svg&&n&&n.paper&&n.paper.safari(),ic.length&&jc(kc)},lc=function(a){return a>255?255:0>a?0:a};$b.animateWith=function(a,b,d,e,f,g){var h=this;if(h.removed)return g&&g.call(h),h;var i=d instanceof r?d:c.animation(d,e,f,g);s(i,h,i.percents[0],null,h.attr());for(var j=0,k=ic.length;k>j;j++)if(ic[j].anim==b&&ic[j].el==a){ic[k-1].start=ic[j].start;break}return h},$b.onAnimation=function(a){return a?b.on("raphael.anim.frame."+this.id,a):b.unbind("raphael.anim.frame."+this.id),this},r.prototype.delay=function(a){var b=new r(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},r.prototype.repeat=function(a){var b=new r(this.anim,this.ms);return b.del=this.del,b.times=N.floor(O(a,0))||1,b},c.animation=function(a,b,d,e){if(a instanceof r)return a;(c.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),b=+b||0;var f,g,h={};for(g in a)a[z](g)&&_(g)!=g&&_(g)+"%"!=g&&(f=!0,h[g]=a[g]);return f?(d&&(h.easing=d),e&&(h.callback=e),new r({100:h},b)):new r(a,b)},$b.animate=function(a,b,d,e){var f=this;if(f.removed)return e&&e.call(f),f;var g=a instanceof r?a:c.animation(a,b,d,e);return s(g,f,g.percents[0],null,f.attr()),f},$b.setTime=function(a,b){return a&&null!=b&&this.status(a,P(b,a.ms)/a.ms),this},$b.status=function(a,b){var c,d,e=[],f=0;if(null!=b)return s(a,this,-1,P(b,1)),this;for(c=ic.length;c>f;f++)if(d=ic[f],d.el.id==this.id&&(!a||d.anim==a)){if(a)return d.status;e.push({anim:d.anim,status:d.status})}return a?0:e},$b.pause=function(a){for(var c=0;cb;b++)!a[b]||a[b].constructor!=$b.constructor&&a[b].constructor!=mc||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},nc=mc.prototype;nc.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],!a||a.constructor!=$b.constructor&&a.constructor!=mc||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},nc.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},nc.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var oc in $b)$b[z](oc)&&(nc[oc]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][D](c,b)})}}(oc));return nc.attr=function(a,b){if(a&&c.is(a,V)&&c.is(a[0],"object"))for(var d=0,e=a.length;e>d;d++)this.items[d].attr(a[d]);else for(var f=0,g=this.items.length;g>f;f++)this.items[f].attr(a,b);return this},nc.clear=function(){for(;this.length;)this.pop()},nc.splice=function(a,b){a=0>a?O(this.length+a,0):a,b=O(0,P(this.length-a,b));var c,d=[],e=[],f=[];for(c=2;cc;c++)e.push(this[a+c]);for(;cc?f[c]:d[c-g];for(c=this.items.length=this.length-=b-g;this[c];)delete this[c++];return new mc(e)},nc.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0},nc.animate=function(a,b,d,e){(c.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h)return this;e&&(g=function(){!--h&&e.call(j)}),d=c.is(d,U)?d:g;var k=c.animation(a,b,d,g);for(f=this.items[--i].animate(k);i--;)this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},nc.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},nc.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=P[D](0,a),b=P[D](0,b),c=O[D](0,c),d=O[D](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},nc.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},nc.toString=function(){return"Raphaël‘s set"},nc.glow=function(a){var b=this.paper.set();return this.forEach(function(c){var d=c.glow(a);null!=d&&d.forEach(function(a){b.push(a)})}),b},nc.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(c=!0,!1):void 0}),c},c.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[z](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=ab(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[z](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"},f.k)for(var g in f.k)f[z](g)&&(b.glyphs[e].k[g]=f.k[g])}}return a},v.getFont=function(a,b,d,e){if(e=e||"normal",d=d||"normal",b=+b||{normal:400,bold:700,lighter:300,bolder:800}[b]||400,c.fonts){var f=c.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,G)+"(\\s|$)","i");for(var h in c.fonts)if(c.fonts[z](h)&&g.test(h)){f=c.fonts[h];break}}var i;if(f)for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=b||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},v.print=function(a,b,d,e,f,g,h,i){g=g||"middle",h=O(P(h||0,1),-1),i=O(P(i||1,3),1);var j,k=I(d)[J](G),l=0,m=0,n=G;if(c.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[J](w),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t])l=0,x=0,m=0,r+=q*i;else{var v=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(v.w||e.w)+(v.k&&v.k[k[t]]||0)+e.w*h:0,m=1}x&&x.d&&(n+=c.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(b-s)/j]))}}return this.path(n).attr({fill:"#000",stroke:"none"})},v.add=function(a){if(c.is(a,"array"))for(var b,d=this.set(),e=0,f=a.length;f>e;e++)b=a[e]||{},x[z](b.type)&&d.push(this[b.type]().attr(b));return d},c.format=function(a,b){var d=c.is(b,V)?[0][E](b):arguments;return a&&c.is(a,U)&&d.length-1&&(a=a.replace(y,function(a,b){return null==d[++b]?G:d[b]})),a||G},c.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),c.ninja=function(){return B.was?A.win.Raphael=B.is:delete Raphael,c},c.st=nc,function(a,b,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):c.eve("raphael.DOMload")}null==a.readyState&&a.addEventListener&&(a.addEventListener(b,d=function(){a.removeEventListener(b,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()}(document,"DOMContentLoaded"),b.on("raphael.DOMload",function(){u=!0}),function(){if(c.svg){var a="hasOwnProperty",b=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=c.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};c.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e)e[a](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),b(e[f])):d.setAttribute(f,b(e[f])))}else d=c._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(a,e){var j="linear",k=a.id+e,m=.5,n=.5,o=a.node,p=a.paper,r=o.style,s=c._g.doc.getElementById(k);if(!s){if(e=b(e).replace(c._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t))return null;var u=[0,0,f.cos(c.rad(t)),f.sin(c.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=c._parseDots(e);if(!w)return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),a.gradient&&k!=a.gradient.id&&(p.defs.removeChild(a.gradient),delete a.gradient),!a.gradient){s=q(j+"Gradient",{id:k}),a.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:a.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff"}))}}return q(o,{fill:"url(#"+k+")",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=b(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;)switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y;c._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=c._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-E*u):(g=E*u,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=c.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-g):(g=0,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:c.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p)if(p[a](k)&&!p[k]){var F=c._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,c,d){if(c=u[b(c).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=c.length;h--;)g[h]=c[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[a](o)){if(!c._availableAttrs[a](o))continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"title":var u=i.getElementsByTagName("title");if(u.length&&(u=u[0]))u.firstChild.nodeValue=p;else{u=q("title");var w=c._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u)}break;case"href":case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var z=q("a");x.insertBefore(z,i),z.appendChild(i),x=z}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var A=b(p).split(j);if(4==A.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var B=q("clipPath"),C=q("rect");B.id=c.createUUID(),q(C,{x:A[0],y:A[1],width:A[2],height:A[3]}),B.appendChild(C),d.paper.defs.appendChild(B),q(i,{"clip-path":"url(#"+B.id+")"}),d.clip=C}if(!p){var D=i.getAttribute("clip-path");if(D){var E=c._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g,l));E&&E.parentNode.removeChild(E),q(i,{"clip-path":l}),delete d.clip}}break;case"path":"path"==d.type&&(q(i,{d:p?k.path=c._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx)break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type)break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy)break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type)break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),d.paper._vbSize&&(p*=d.paper._vbSize),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var F=b(p).match(c._ISURL);if(F){B=q("pattern");var G=q("image");B.id=c.createUUID(),q(B,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(G,{x:0,y:0,"xlink:href":F[1]}),B.appendChild(G),function(a){c._preload(F[1],function(){var b=this.offsetWidth,c=this.offsetHeight;q(a,{width:b,height:c}),q(G,{width:b,height:c}),d.paper.safari()})}(B),d.paper.defs.appendChild(B),q(i,{fill:"url(#"+B.id+")"}),d.pattern=B,d.pattern&&s(d);break}var H=c.getRGB(p);if(H.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=b(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var I=c._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(I){var J=I.getElementsByTagName("stop");q(J[J.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}}else delete f.gradient,delete k.gradient,!c.is(k.opacity,"undefined")&&c.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!c.is(k["fill-opacity"],"undefined")&&c.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});H[a]("opacity")&&q(i,{"fill-opacity":H.opacity>1?H.opacity/100:H.opacity});case"stroke":H=c.getRGB(p),i.setAttribute(o,H.hex),"stroke"==o&&H[a]("opacity")&&q(i,{"stroke-opacity":H.opacity>1?H.opacity/100:H.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=b(p).charAt())&&r(d,p);break;case"opacity":k.gradient&&!k[a]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){I=c._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),I&&(J=I.getElementsByTagName("stop"),q(J[J.length-1],{"stop-opacity":p}));break}default:"font-size"==o&&(p=e(p,10)+"px");var K=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[K]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[a]("text")||f[a]("font")||f[a]("font-size")||f[a]("x")||f[a]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(c._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;
if(f[a]("text")){for(g.text=f.text;h.firstChild;)h.removeChild(h.firstChild);for(var j,k=b(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++)j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(c._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++)n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&c.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.matrix=c.matrix(),this.realPath=null,this.paper=b,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},A=c.el;z.prototype=A,A.constructor=z,c._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new z(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},A.rotate=function(a,c,e){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this.transform(this._.transform.concat([["r",a,c,e]])),this},A.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,c,e,f]])),this},A.translate=function(a,c){return this.removed?this:(a=b(a).split(j),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this.transform(this._.transform.concat([["t",a,c]])),this)},A.transform=function(b){var d=this._;if(null==b)return d.transform;if(c._extractTransform(this,b),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[a]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},A.hide=function(){return!this.removed&&this.paper.safari(this.node.style.display="none"),this},A.show=function(){return!this.removed&&this.paper.safari(this.node.style.display=""),this},A.remove=function(){if(!this.removed&&this.node.parentNode){var a=this.paper;a.__set__&&a.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&a.defs.removeChild(this.gradient),c._tear(this,a),"a"==this.node.parentNode.tagName.toLowerCase()?this.node.parentNode.parentNode.removeChild(this.node.parentNode):this.node.parentNode.removeChild(this.node);for(var b in this)this[b]="function"==typeof this[b]?c._removedFactory(b):null;this.removed=!0}},A._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}return a&&this.hide(),b},A.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,"string")){if("fill"==b&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if("transform"==b)return this._.transform;for(var g=b.split(j),h={},i=0,l=g.length;l>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],"function")?this.paper.customAttributes[b].def:c._availableAttrs[b];return l-1?h:h[g[0]]}if(null==d&&c.is(b,"array")){for(h={},i=0,l=b.length;l>i;i++)h[b[i]]=this.attr(b[i]);return h}if(null!=d){var m={};m[b]=d}else null!=b&&c.is(b,"object")&&(m=b);for(var n in m)k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[a](n)&&m[a](n)&&c.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[a](p)&&(m[p]=o[p])}return w(this,m),this},A.toFront=function(){if(this.removed)return this;"a"==this.node.parentNode.tagName.toLowerCase()?this.node.parentNode.parentNode.appendChild(this.node.parentNode):this.node.parentNode.appendChild(this.node);var a=this.paper;return a.top!=this&&c._tofront(this,a),this},A.toBack=function(){if(this.removed)return this;var a=this.node.parentNode;"a"==a.tagName.toLowerCase()?a.parentNode.insertBefore(this.node.parentNode,this.node.parentNode.parentNode.firstChild):a.firstChild!=this.node&&a.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper);this.paper;return this},A.insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;return b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this},A.insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;return b.parentNode.insertBefore(this.node,b),c._insertbefore(this,a,this.paper),this},A.blur=function(a){var b=this;if(0!==+a){var d=q("filter"),e=q("feGaussianBlur");b.attrs.blur=a,d.id=c.createUUID(),q(e,{stdDeviation:+a||1.5}),d.appendChild(e),b.paper.defs.appendChild(d),b._blur=d,q(b.node,{filter:"url(#"+d.id+")"})}else b._blur&&(b._blur.parentNode.removeChild(b._blur),delete b._blur,delete b.attrs.blur),b.node.removeAttribute("filter");return b},c._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new z(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},c._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);return h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},c._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},c._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},c._engine.text=function(a,b,d,e){var f=q("text");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);return g.attrs={x:b,y:d,"text-anchor":"middle",text:e,font:c._availableAttrs.font,stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},c._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a&&a.container,d=a.x,e=a.y,f=a.width,g=a.height;if(!b)throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg"}),1==b?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",c._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i)),b=new c._Paper,b.width=f,b.height=g,b.canvas=i,b.clear(),b._left=b._top=0,h&&(b.renderfix=function(){}),b.renderfix(),b},c._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=g(c/this.width,d/this.height),j=this.top,l=e?"xMidYMid meet":"xMinYMin";for(null==a?(this._vbSize&&(i=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=i,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:l});i&&j;)h="stroke-width"in j.attrs?j.attrs["stroke-width"]:1,j.attr({"stroke-width":h}),j._.dirty=1,j._.dirtyT=1,j=j.prev;return this._viewBox=[a,b,c,d,!!e],this},c.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()}var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},c.prototype.clear=function(){c.eve("raphael.clear",this);for(var a=this.canvas;a.firstChild;)a.removeChild(a.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(c._g.doc.createTextNode("Created with Raphaël "+c.version)),a.appendChild(this.desc),a.appendChild(this.defs=q("defs"))},c.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null};var B=c.st;for(var C in A)A[a](C)&&!B[a](C)&&(B[C]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(C))}}(),function(){if(c.vml){var a="hasOwnProperty",b=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=c.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(a){var d=/[ahqstv]/gi,e=c._pathToAbsolute;if(b(a).match(d)&&(e=c._path2curve),d=/[clmz]/g,e==c._pathToAbsolute&&!b(a).match(d)){var g=b(a).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g}var h,i,j=e(a);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++)i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)}return g.join(n)},y=function(a,b,d){var e=c.matrix();return e.rotate(-a,.5,.5),{dx:e.x(b,d),dy:e.y(b,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy}if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-q+n+e*-r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)}m.visibility="visible"}};c.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,c,d){for(var e=b(c).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i)i[a](t)&&(m[t]=i[t]);if(q&&(m.path=c._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~b(m.path).toLowerCase().indexOf("r")?c._pathToAbsolute(m.path):m.path),"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=c.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1}if("clip-rect"in i){var G=b(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||c._g.doc.createElement("div"),I=H.style;I.clip=c.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])}if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=b(i.fill).match(c._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],c._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else K.color=c.getRGB(i.fill).hex,K.src=o,K.type="solid",c.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=b(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+c.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")}l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=c.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),"stroke-dasharray"in i){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[a](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o}Q&&l.appendChild(P)}if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=b(s.textpath.string).replace(/"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=c.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++)if(Y[Z]in i){s._.dirty=1;break}switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0}s.textpath.style["v-text-kern"]=!0}},C=function(a,f,g){a.attrs=a.attrs||{};var h=(a.attrs,Math.pow),i="linear",j=".5 .5";if(a.attrs.gradient=f,f=b(f).replace(c._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k))return null}var l=c._parseDots(f);if(!l)return null;if(a=a.shape||a.node,l.length){a.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++)l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),a.appendChild(g)}return 1},D=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=b,this.matrix=c.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},E=c.el;D.prototype=E,E.constructor=D,E.transform=function(a){if(null==a)return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=a=b(a).replace(/\.{3}|\u2026/g,this._.transform||o)),c._extractTransform(this,f+a);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~b(this.attrs.fill).indexOf("-"),l=!b(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type)if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else j.style.filter=o,i.matrix=b(h),i.offset=h.offset();return d&&(this._.transform=d),this},E.rotate=function(a,c,e){if(this.removed)return this;if(null!=a){if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,c,e]])),this}},E.translate=function(a,c){return this.removed?this:(a=b(a).split(k),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=c),this.transform(this._.transform.concat([["t",a,c]])),this)},E.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,c,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),c.eve.unbind("raphael.*.*."+this.id),c._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null;this.removed=!0}},E.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,"string")){if(b==j&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var g=b.split(k),h={},i=0,m=g.length;m>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],"function")?this.paper.customAttributes[b].def:c._availableAttrs[b];return m-1?h:h[g[0]]}if(this.attrs&&null==d&&c.is(b,"array")){for(h={},i=0,m=b.length;m>i;i++)h[b[i]]=this.attr(b[i]);return h}var n;null!=d&&(n={},n[b]=d),null==d&&c.is(b,"object")&&(n=b);for(var o in n)l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[a](o)&&n[a](o)&&c.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[a](q)&&(n[q]=p[q])}n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&c._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper)),this)},E.insertAfter=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[a.length-1]),a.node.nextSibling?a.node.parentNode.insertBefore(this.node,a.node.nextSibling):a.node.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this)},E.insertBefore=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[0]),a.node.parentNode.insertBefore(this.node,a.node),c._insertbefore(this,a,this.paper),this)},E.blur=function(a){var b=this.node.runtimeStyle,d=b.filter;return d=d.replace(r,o),0!==+a?(this.attrs.blur=a,b.filter=d+n+m+".Blur(pixelradius="+(+a||1.5)+")",b.margin=c.format("-{0}px 0 0 -{0}px",f(+a||1.5))):(b.filter=d,b.margin=0,delete this.attrs.blur),this},c._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},c._engine.rect=function(a,b,d,e,f,g){var h=c._rectPath(b,d,e,f,g),i=a.path(h),j=i.attrs;return i.X=j.x=b,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},c._engine.ellipse=function(a,b,c,d,e){{var f=a.path();f.attrs}return f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},c._engine.circle=function(a,b,c,d){{var e=a.path();e.attrs}return e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},c._engine.image=function(a,b,d,e,f,g){var h=c._rectPath(d,e,f,g),i=a.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=b,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=b,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},c._engine.text=function(a,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=c.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=b(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,a),l={fill:"#000",stroke:"none",font:c._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=b(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),a.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},c._engine.setSize=function(a,b){var d=this.canvas.style;return this.width=a,this.height=b,a==+a&&(a+="px"),b==+b&&(b+="px"),d.width=a,d.height=b,d.clip="rect(0 "+a+" "+b+" 0)",this._viewBox&&c._engine.setViewBox.apply(this,this._viewBox),this},c._engine.setViewBox=function(a,b,d,e,f){c.eve("raphael.setViewBox",this,this._viewBox,[a,b,d,e,f]);var h,i,j=this.width,k=this.height,l=1/g(d/j,e/k);return f&&(h=k/e,i=j/d,j>d*h&&(a-=(j-d*h)/2/h),k>e*i&&(b-=(k-e*i)/2/i)),this._viewBox=[a,b,d,e,!!f],this._viewBoxShift={dx:-a,dy:-b,scale:l},this.forEach(function(a){a.transform("...")}),this};var F;c._engine.initWin=function(a){var b=a.document;b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},c._engine.initWin(c._g.win),c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a.container,d=a.height,e=a.width,f=a.x,g=a.y;if(!b)throw new Error("VML container not found.");var h=new c._Paper,i=h.canvas=c._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=c._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=c.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==b?(c._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i),h.renderfix=function(){},h},c.prototype.clear=function(){c.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=c._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},c.prototype.remove=function(){c.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null;return!0};var G=c.st;for(var H in E)E[a](H)&&!G[a](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}}(),B.was?A.win.Raphael=c:Raphael=c,c});
================================================
FILE: examples/worzone/maze.js
================================================
(function (Game) {
var mazes = [
[ "*******************",
"* *",
"* ******* ****** *",
"* * * *",
"* * ******* * *",
"* * * * * *",
"* * * *",
"* C *",
"* * ******* * *",
"* * * *",
"* * * *",
"* * * *",
"* ******* ****** *",
"* *",
"* *************** *",
"*1*5XXXXXLXXXX60*2*",
"***XXXXXXXXXXXXX***" ],
[ "*******************",
"* *",
"* ******* ****** *",
"* * * *",
"* * * ******* * * *",
"* * * * * * * *",
"* * * * * * * *",
"* * * C * *",
"* * * *** *** *****",
"* * * * * * * *",
"* * * * * * * * * *",
"* * * * *",
"***** *** * ***** *",
"* * * *",
"* *************** *",
"*1*5XXXXXLXXXX60*2*",
"***XXXXXXXXXXXXX***" ]
];
function Maze(level) {
var data = mazes[(level + 1) % 2],
blockSize = 50,
wall = 5,
ascii = new Game.AsciiGraphic(data, blockSize, wall);
function isWall(blockPos) { return ascii.isChar(blockPos, "*"); }
function isFree(blockPos) { return ascii.isChar(blockPos, "C "); }
function findMazePos(character) {
function blockThat(predicate) {
return ascii.forEachBlock(function(blockPos) {
if (predicate(blockPos)) { return blockPos; }
});
}
return blockThat(function(blockPos) { return ascii.isChar(blockPos, character)});
}
function accessible(pos, objectRadiusX, objectRadiusY, predicate) {
objectRadiusY || (objectRadiusY = objectRadiusX);
var radiusX = objectRadiusX,
radiusY = objectRadiusY;
for (var x = ascii.toBlockX(pos.x - radiusX); x <= ascii.toBlockX(pos.x + radiusX); x++) {
for (var y = ascii.toBlockY(pos.y - radiusY); y <= ascii.toBlockY(pos.y + radiusY); y++) {
if (!predicate(new Point(x, y))) { return false; }
}
}
return true;
}
return {
levelNumberPos : function() {
return ascii.blockCenter(findMazePos("L"))
},
centerMessagePos : function() {
return ascii.blockCenter(findMazePos("C"))
},
playerStartPos : function(player) {
return ascii.blockCenter(findMazePos("" + player.id))
},
playerScorePos : function(player) {
var number = Number(player.id) + 4
return ascii.blockCenter(findMazePos("" + number))
},
isAccessible : function(pos, objectRadiusX, objectRadiusY) {
return accessible(pos, objectRadiusX, objectRadiusY, function(blockPos) { return !isWall(blockPos) })
},
isAccessibleByMonster : function(pos, objectRadiusX, objectRadiusY) {
return accessible(pos, objectRadiusX, objectRadiusY, function(blockPos) { return isFree(blockPos) })
},
randomFreePos : function(filter) {
while(true) {
var pixelPos = ascii.blockCenter(ascii.randomBlock());
if (filter(pixelPos)) { return pixelPos; }
}
},
draw : function(levelEnd, raphael) {
var elements = ascii.renderWith(raphael, function(block) {
if (isWall(block)) {
var corner = ascii.blockCorner(block),
size = ascii.sizeOf(block);
return raphael.rect(corner.x, corner.y, size.x, size.y).attr({ stroke : "#008", fill : "#008"});
}
});
levelEnd.subscribeOnNext(function() {
elements.remove()
});
}
}
}
Game.Maze = Maze;
}(window.Game));
================================================
FILE: examples/worzone/readme.md
================================================
================================================
FILE: examples/worzone/rectangle.js
================================================
(function (Game) {
function Rectangle(x, y, width, height) {
return {x : x, y : y, width : width, height : height}
}
Game.Rectangle = Rectangle;
}(window.Game));
================================================
FILE: examples/worzone/rx.dom.lite.js
================================================
;(function (factory) {
var objectTypes = {
'boolean': false,
'function': true,
'object': true,
'number': false,
'string': false,
'undefined': false
};
var root = (objectTypes[typeof window] && window) || this,
freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
freeGlobal = objectTypes[typeof global] && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
root = freeGlobal;
}
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.dom = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Header values
var AnonymousObservable = Rx.AnonymousObservable,
fromEvent = Rx.Observable.fromEvent;
function noop () { }
var dom = {
ready: function () {
return new AnonymousObservable(function (observer) {
function handler () {
observer.onNext();
observer.onCompleted();
}
function createListener() {
if (document.addEventListener) {
document.addEventListener( 'DOMContentLoaded', handler, false );
root.addEventListener( 'load', handler, false );
return function () {
document.removeEventListener( 'DOMContentLoaded', handler, false );
root.removeEventListener( 'load', handler, false );
};
} else if (document.attachEvent) {
document.attachEvent( 'onDOMContentLoaded', handler );
root.attachEvent( 'onload', handler );
return function () {
document.attachEvent( 'DOMContentLoaded', handler );
root.attachEvent( 'load', handler );
};
} else {
document['onload'] = handler;
root['onDOMContentLoaded'] = handler;
return function () {
document['onload'] = null;
root['onDOMContentLoaded'] = null;
};
}
}
var returnFn = noop;
if (document.readyState === "complete") {
setTimeout(handler, 0);
} else {
returnFn = createListener();
}
return returnFn;
}).publish().refCount();
}
};
// Add every event possible to dom
(function () {
var events = "blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu";
if (root.PointerEvent) {
events += " pointerdown pointerup pointermove pointerover pointerout pointerenter pointerleave";
}
if (root.TouchEvent) {
events += " touchstart touchend touchmove touchcancel";
}
events = events.split(' ');
for(var i = 0, len = events.length; i < len; i++) {
(function (e) {
dom[e] = function (element, selector) {
return fromEvent(element, e, selector);
};
}(events[i]))
}
}());
return dom;
}));
================================================
FILE: examples/worzone/vector.js
================================================
// Originally from https://github.com/raimohanska/worzone
;(function (global) {
function Point(x, y) {
return new Vector2D(x, y);
}
// Number -> Number -> Vector2D
function Vector2D(x, y) {
this.x = x;
this.y = y;
}
Vector2D.prototype = {
// Vector2D -> Vector2D
add : function(other) { return new Vector2D(this.x + other.x, this.y + other.y); },
// Vector2D -> Vector2D
subtract : function(other) { return new Vector2D(this.x - other.x, this.y - other.y); },
// Unit -> Number
getLength : function() { return Math.sqrt(this.x * this.x + this.y * this.y); },
// Number -> Vector2D
times : function(multiplier) { return new Vector2D(this.x * multiplier, this.y * multiplier); },
// Unit -> Vector2D
invert : function() { return new Vector2D(-this.x, -this.y); },
// Number -> Vector2D
withLength : function(newLength) { return this.times(newLength / this.getLength()); },
rotateRad : function(radians) {
var length = this.getLength(),
currentRadians = this.getAngle(),
resultRadians = radians + currentRadians,
rotatedUnit = new Vector2D(Math.cos(resultRadians), Math.sin(resultRadians));
return rotatedUnit.withLength(length);
},
// Number -> Vector2D
rotateDeg : function(degrees) {
var radians = degrees * 2 * Math.PI / 360;
return this.rotateRad(radians);
},
// Unit -> Number
getAngle : function() {
var length = this.getLength(),
unit = this.withLength(1);
return Math.atan2(unit.y, unit.x);
},
getAngleDeg : function() {
return this.getAngle() * 360 / (2 * Math.PI);
},
floor : function() {
return new Vector2D(Math.floor(this.x), Math.floor(this.y));
},
toString : function() {
return '(' + x + ', ' + y + ')';
}
};
global.Game = {
Point: Point,
Vector2D: Vector2D
};
}(window));
================================================
FILE: examples/wsh/example1.js
================================================
function include(jsFile) {
var fso = new ActiveXObject("Scripting.FileSystemObject"),
f = fso.OpenTextFile(jsFile, 1),
s = f.ReadAll();
f.Close();
return s;
}
eval(include("..\\..\\dist\\rx.all.js"));
function next(x) {
WScript.Echo(x);
}
Rx.Observable.timer(500).subscribe(next);
================================================
FILE: examples/wsh/readme.md
================================================
================================================
FILE: index.js
================================================
var Rx = require('./dist/rx');
require('./dist/rx.aggregates');
require('./dist/rx.async');
require('./dist/rx.backpressure');
require('./dist/rx.binding');
require('./dist/rx.coincidence');
require('./dist/rx.experimental');
require('./dist/rx.joinpatterns');
require('./dist/rx.sorting');
require('./dist/rx.virtualtime');
require('./dist/rx.testing');
require('./dist/rx.time');
module.exports = Rx;
================================================
FILE: lib/anonymousobserver.js
================================================
'use strict';
var AnonymousSafeObserver = require('./anonymousobserver');
var ObserverBase = require('./observerbase');
var inherits = require('inherits');
function AnonymousObserver(next, error, complete) {
this._next = next;
this._error = error;
this._complete = complete;
ObserverBase.call(this);
}
inherits(AnonymousObserver, ObserverBase);
AnonymousObserver.prototype.makeSafe = function (d) {
return new AnonymousSafeObserver(this._next.bind(this), this._error.bind(this), this._complete.bind(this), d);
};
module.exports = AnonymousObserver;
================================================
FILE: lib/anonymoussafeobserver.js
================================================
'use strict';
function AnonymousSafeObserver(next, error, complete, disposable) {
this._next = next;
this._error = error;
this._complete = complete;
this._disposable = disposable;
this._stopped = false;
}
AnonymousSafeObserver.prototype.next = function (x) {
if (this._stopped) { return; }
var noError = false;
try {
this._next(x);
noError = true;
} finally {
!noError && this._disposable.dispose();
}
};
AnonymousSafeObserver.prototype.error = function (e) {
if (!this._stopped) {
try {
this._error(e);
} finally {
this._disposable.dispose();
}
}
};
AnonymousSafeObserver.prototype.complete = function () {
if (!this._stopped) {
try {
this._complete();
} finally {
this._disposable.dispose();
}
}
};
module.exports = AnonymousSafeObserver;
================================================
FILE: lib/concurrency/queuescheduler.js
================================================
'use strict';
var Scheduler = require('./scheduler');
var ScheduledItem = require('./scheduleditem');
var PriorityQueue = require('../internal/priorityqueue');
var inherits = require('inherits');
function QueueScheduler() {
Scheduler.call(this);
}
QueueScheduler.queue = null;
inherits(QueueScheduler, Scheduler);
function runTrampoline () {
while (QueueScheduler.queue.length > 0) {
var item = QueueScheduler.queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
QueueScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!QueueScheduler.queue) {
QueueScheduler.queue = new PriorityQueue(4);
QueueScheduler.queue.enqueue(si);
try {
runTrampoline();
} finally {
QueueScheduler.queue = null;
}
} else {
QueueScheduler.queue.enqueue(si);
}
return si.disposable;
};
QueueScheduler.prototype.scheduleRequired = function () { return !QueueScheduler.queue; };
module.exports = QueueScheduler;
================================================
FILE: lib/concurrency/scheduler.js
================================================
'use strict';
var Disposable = require('../disposables/disposable');
var CompositeDisposable = require('../disposables/compositedisposable');
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.schedule = function (state, action) { };
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
Scheduler.prototype._scheduleFuture = function (state, dueTime, action) { };
function PeriodicDisposable(id) {
this._id = id;
this.isDisposed = false;
}
PeriodicDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
global.clearInterval(this._id);
}
};
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
Scheduler.prototype.schedulePeriodic = function(state, period, action) {
if (typeof global.setInterval === 'undefined') { throw new Error('setInterval not supported'); }
period = Scheduler.normalize(period);
var s = state, id = global.setInterval(function () { s = action(s); }, period);
return new PeriodicDisposable(id);
};
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return Disposable.empty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return Disposable.empty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
var defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date(); }; }());
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
module.exports = Scheduler;
var CurrentThreadScheduler = require('./scheduler/currentthreadscheduler');
var ImmediateScheduler = require('./scheduler/immediatescheduler');
var DefaultScheduler = require('./scheduler/defaultscheduler');
var CatchScheduler = require('./scheduler/catchscheduler');
Scheduler.queue = Scheduler.currentThread = new CurrentThreadScheduler();
Scheduler.async = Scheduler['default'] = Scheduler.timeout = new DefaultScheduler();
Scheduler.immediate = new ImmediateScheduler();
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
Scheduler.prototype['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
================================================
FILE: lib/disposables/binarydisposable.js
================================================
'use strict';
function BinaryDisposable(first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
}
BinaryDisposable.prototype.dispose = BinaryDisposable.prototype.unsubscribe = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
module.exports = BinaryDisposable;
================================================
FILE: lib/disposables/compositedisposable.js
================================================
'use strict';
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
function CompositeDisposable () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
len = args.length;
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
}
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposable.prototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposable.prototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposable.prototype.dispose = CompositeDisposable.prototype.unsubscribe = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
module.exports = CompositeDisposable;
================================================
FILE: lib/disposables/disposable.js
================================================
'use strict';
var noop = require('../internal/noop');
var isFunction = require('../internal/isfunction');
var ObjectDisposedError = require('../internal/errors').ObjectDisposedError;
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
function Disposable (action) {
this.isDisposed = false;
this.action = action || noop;
}
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = Disposable.prototype.unsubscribe = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
Disposable._fixup = function (result) {
return Disposable.isDisposable(result) ? result : Disposable.empty;
};
module.exports = Disposable;
================================================
FILE: lib/disposables/singleassignmentdisposable.js
================================================
'use strict';
function SingleAssignmentDisposable () {
this.isDisposed = false;
this._current = null;
}
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this._current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this._current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this._current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = SingleAssignmentDisposable.prototype.unsubscribe = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this._current;
this._current = null;
old && old.dispose();
}
};
module.exports = SingleAssignmentDisposable;
================================================
FILE: lib/internal/errors.js
================================================
'use strict';
function EmptyError () {
this.message = 'Sequence contains no elements.';
Error.call(this);
}
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
function ObjectDisposedError() {
this.message = 'Object has been disposed';
Error.call(this);
}
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
function ArgumentOutOfRangeError() {
this.message = 'Argument out of range';
Error.call(this);
}
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
function NotSupportedError(message) {
this.message = message || 'This operation is not supported';
Error.call(this);
}
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
function NotImplementedError(message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
}
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
function CompositeError (errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
}
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
module.exports = {
CompositeError: CompositeError,
EmptyError: EmptyError,
ObjectDisposedError: ObjectDisposedError,
ArgumentOutOfRangeError: ArgumentOutOfRangeError,
NotSupportedError: NotSupportedError,
NotImplementedError: NotImplementedError
};
================================================
FILE: lib/internal/isfunction.js
================================================
'use strict';
module.exports = (function () {
var isFn = function (value) {
return typeof value === 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value === 'function' &&
Object.prototype.toString.call(value) === '[object Function]';
};
}
return isFn;
}());
================================================
FILE: lib/internal/noop.js
================================================
'use strict';
module.exports = function noop () { };
================================================
FILE: lib/internal/priorityqueue.js
================================================
'use strict';
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
function PriorityQueue (capacity) {
this.items = new Array(capacity);
this.length = 0;
}
PriorityQueue.prototype.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
PriorityQueue.prototype.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
PriorityQueue.prototype.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
PriorityQueue.prototype.peek = function () { return this.items[0].value; };
PriorityQueue.prototype.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
PriorityQueue.prototype.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
PriorityQueue.prototype.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
PriorityQueue.prototype.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
module.exports = PriorityQueue;
================================================
FILE: lib/internal/producer.js
================================================
'use strict';
var BinaryDisposable = require('../disposables/binarydisposable');
var Disposable = require('../disposables/disposable');
var SingleAssignmentDisposable = require('../disposables/singleassignmentdisposable');
var SafeObserver = require('./safeobserver');
var Scheduler = require('../concurrency/scheduler');
function Producer () {
}
Producer.prototype.subscribe = function (o) {
this._subscribeRaw(o);
};
Producer.prototype._subscribeRaw = function (o, enableSafeguard) {
var state = {
observer: o,
sink: new SingleAssignmentDisposable(),
subscription: new SingleAssignmentDisposable(),
assign: function (s) { this.sink.setDisposable(s); }
};
var d = new BinaryDisposable(state.sink, state.subscription);
if (enableSafeguard) {
state.observer = SafeObserver.create(state.observer, d);
}
if (Scheduler.queue.isScheduleRequired) {
Scheduler.queue.schedule(state, this.run.bind(this));
} else {
state.subscription.setDisposable(this._run(state.observer, state.subscription, state.assign.bind(state)));
}
};
Producer.prototype.run = function (s, x) {
x.subscription.setDisposable(this._run(x.observer, x.subscription, x.assign.bind(x)));
return Disposable.empty;
};
Producer.prototype._run = function (o, cancel, setSink) { };
module.exports = Producer;
================================================
FILE: lib/internal/safeobserver.js
================================================
'use strict';
var AnonymousObserver = require('../anonymousobserver');
function SafeObserver(o, disposable) {
this._o = o;
this._disposable = disposable;
}
SafeObserver.create = function (o, disposable) {
if (o instanceof AnonymousObserver) {
return o.makeSafe(disposable);
}
return new SafeObserver(o, disposable);
};
SafeObserver.prototype.next = function (x) {
var noError = false;
try {
this._o.next(x);
noError = true;
} finally {
!noError && this._disposable.dispose();
}
};
SafeObserver.prototype.error = function (e) {
try {
this._o.error(e);
} finally {
this._disposable.dispose();
}
};
SafeObserver.prototype.complete = function () {
try {
this._o.complete();
} finally {
this._disposable.dispose();
}
};
module.exports = SafeObserver;
================================================
FILE: lib/internal/sink.js
================================================
'use strict';
var noop = require('./noop');
var NoOpObserver = {
next: noop,
error: noop,
complete: noop
};
function Forwarder(fwd) {
this._fwd = fwd;
}
Forwarder.prototype.next = function (x) {
this._fwd._o.next(x);
};
Forwarder.prototype.error = function (e) {
this._fwd._o.error(e);
};
Forwarder.prototype.complete = function () {
this._fwd._o.complete();
this._fwd.dispose();
};
function Sink(o, cancel) {
this._o = o;
this._cancel = cancel;
}
Sink.prototype.dispose = function () {
this._o = NoOpObserver;
var cancel = this._cancel;
this._cancel = null;
cancel && cancel.dispose();
};
Sink.prototype.getForwarder = function () {
return new Forwarder(this);
};
module.exports = Sink;
================================================
FILE: lib/internal/throwerror.js
================================================
'use strict';
module.exports = function throwError (e) { throw e; };
================================================
FILE: lib/observable.js
================================================
'use strict';
var AnonymousObserver = require('./anonymousobserver');
var noop = require('../internal/noop');
var throwError = require('../internal/throwError');
function Observable() { }
Observable.subscribe = function (oOrNext, error, complete) {
if (typeof oOrNext === 'object') {
return this._subscribe(oOrNext);
}
return this._subscribe(new AnonymousObserver(oOrNext || noop, error || throwError, complete || noop));
};
module.exports = Observable;
================================================
FILE: lib/observablebase.js
================================================
'use strict';
var AutoDetachObserver = require('./internal/autodetachobserver');
var Observable = require('./observable');
var Disposable = require('../disposables/disposable');
var Scheduler = require('../concurrency/scheduler');
var inherits = require('inherits');
function ObservableBase() {
Observable.call(this);
}
inherits(ObservableBase, Observable);
function scheduledSubscribe(_, state) {
var self = state.self, ado = state.ado;
try {
ado.setDisposable(self._subscribeCore(ado));
} catch (e) {
if (!ado.fail(e)) { throw e; }
}
return Disposable.empty;
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o);
var state = { self: this, ado: ado };
if (Scheduler.queue.isScheduleRequired()) {
ado.setDisposable(Scheduler.queue.schedule(state, scheduledSubscribe));
} else {
scheduledSubscribe(null, state);
}
return ado;
};
ObservableBase.prototype._subscribeCore = function (o) { };
module.exports = ObservableBase;
================================================
FILE: lib/observerbase.js
================================================
'use strict';
function ObserverBase() {
this._stopped = false;
}
ObserverBase.prototype.next = function (x) {
!this._stopped && this._next(x);
};
ObserverBase.prototype._next = function (x) { };
ObserverBase.prototype.error = function (e) {
if (!this._stopped) {
this._stopped = true;
this._error(e);
}
};
ObserverBase.prototype._error = function (e) { };
ObserverBase.prototype.complete = function () {
if (!this._stopped) {
this._stopped = true;
this._complete();
}
};
ObserverBase.prototype._complete = function () { };
ObserverBase.prototype.dispose = ObserverBase.prototype.unsubscribe = function () {
this._stopped = true;
};
ObserverBase.prototype.fail = function (e) {
if (!this._stopped) {
this._stopped = true;
this._error(e);
return true;
}
return false;
};
module.exports = ObserverBase;
================================================
FILE: license.txt
================================================
Copyright (c) Microsoft. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at http://rx.codeplex.com/wikipage?title=Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/publish.js
================================================
var fs = require('fs');
var execSync = require('child_process').execSync;
var files = fs.readdirSync(process.cwd());
for (var i = 0; i < files.length; i++) {
var file = files[i];
var stat = fs.statSync(file);
if (stat.isDirectory()) {
console.log('publishing %s', file);
execSync('npm publish ' + file);
console.log('published %s', file);
}
}
================================================
FILE: modules/rx-core/package.json
================================================
{
"name": "rx-core",
"title": "Reactive Extensions for JavaScript (RxJS) Core",
"description": "Core library for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.core.js"
},
"browser": {
"index.js": "rx.core.js"
},
"dependencies": {},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.core.js"
}
================================================
FILE: modules/rx-core/readme.md
================================================
# RxJS Core Module #
The Reactive Extensions for JavaScript's core functionality for conforming to the RxJS contract can be found here. This module contains only the bare essentials including Disposables, Schedulers, Observer and Observable. This is made available with the `rx.core.js` file. The primary use case for this file is for those who want to implement a minimal implementation of RxJS for their own usage.
## Details ##
Files:
- [`rx.core.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.js)
NPM Packages:
- [`rx-core`](https://www.npmjs.com/package/rx-core)
NuGet Packages:
- _None_
## Included Classes ##
### Core Objects
- [`Rx.Observer`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observer.md)
- [`Rx.Observable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
### `Observable Methods`
- [`create`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md)
### Schedulers
- [`Rx.Scheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/compositedisposable.md)
- [`Rx.Disposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/disposable.md)
- [`Rx.SerialDisposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/disposables/singleassignmentdisposable.md)
================================================
FILE: modules/rx-core/rx.core.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var
noop = Rx.helpers.noop = function () { },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && !isFunction(p.subscribe) && isFunction(p.then); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); }
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Error.prototype;
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Error.prototype;
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: modules/rx-core-binding/package.json
================================================
{
"name": "rx-core-binding",
"title": "Reactive Extensions for JavaScript (RxJS) Core",
"description": "Core binding library for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.core.binding.js"
},
"browser": {
"index.js": "rx.core.binding.js"
},
"dependencies": {
"rx-core": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.core.binding.js"
}
================================================
FILE: modules/rx-core-binding/readme.md
================================================
# RxJS Core Binding Module #
The Reactive Extensions for JavaScript has a notion of hot and cold observables. Hot observables fire whether you are listening to them or not, such as mouse movements. Cold observables on the other hand, such as a sequence created from an array will fire the same sequence to all subscribers. The Core Binding module gives you the ability to replay events for hot observables, and to turn cold observables into hot observables. The primary use case is for those who are implementing libraries compatible with RxJS to be able to handle hot and cold observables.
## Details ##
Files:
- [`rx.core.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.binding.js)
NPM Packages:
- [`rx-core-binding`](https://www.npmjs.com/package/rx-core-binding)
NuGet Packages:
- _None_
File Dependencies:
- [`rx.core.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.js)
NuGet Dependencies:
- _None_
## Included Observable Operators ##
### `Observable Instance Methods`
- [`connect`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/connect.md)
- [`publish`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publish.md)
- [`publishLast`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publishlast.md)
- [`publishValue`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publishvalue.md)
- [`refCount`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/refcount.md)
- [`replay`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/replay.md)
- [`share`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md)
- [`shareLast`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharelast.md)
- [`shareReplay`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharereplay.md)
- [`shareValue`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharevalue.md)
- [`singleInstance`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/singleinstance.md)
## Included Classes ##
### Subjects
- [`Rx.AsyncSubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/asyncsubject.md)
- [`Rx.Subject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md)
- [`Rx.BehaviorSubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.mdapi/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.mdapi/subjects/replaysubject.md)
================================================
FILE: modules/rx-core-binding/rx.core.binding.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.core'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx.core'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
Observer = Rx.Observer,
AbstractObserver = Rx.internals.AbstractObserver,
disposableCreate = Rx.Disposable.create,
disposableEmpty = Rx.Disposable.empty,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
SerialDisposable = Rx.SerialDisposable,
currentThreadScheduler = Rx.Scheduler.currentThread,
isFunction = Rx.helpers.isFunction,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
checkDisposed = Rx.Disposable.checkDisposed;
// Utilities
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var MulticastObservable = (function (__super__) {
inherits(MulticastObservable, __super__);
function MulticastObservable(source, fn1, fn2) {
this.source = source;
this._fn1 = fn1;
this._fn2 = fn2;
__super__.call(this);
}
MulticastObservable.prototype.subscribeCore = function (o) {
var connectable = this.source.multicast(this._fn1());
return new BinaryDisposable(this._fn2(connectable).subscribe(o), connectable.connect());
};
return MulticastObservable;
}(ObservableBase));
/**
* Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
* subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
* invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
*
* @example
* 1 - res = source.multicast(observable);
* 2 - res = source.multicast(function () { return new Subject(); }, function (x) { return x; });
*
* @param {Function|Subject} subjectOrSubjectSelector
* Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
* Or:
* Subject to push source elements into.
*
* @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
var RefCountObservable = (function (__super__) {
inherits(RefCountObservable, __super__);
function RefCountObservable(source) {
this.source = source;
this._count = 0;
this._connectableSubscription = null;
__super__.call(this);
}
RefCountObservable.prototype.subscribeCore = function (o) {
var subscription = this.source.subscribe(o);
++this._count === 1 && (this._connectableSubscription = this.source.connect());
return new RefCountDisposable(this, subscription);
};
function RefCountDisposable(p, s) {
this._p = p;
this._s = s;
this.isDisposed = false;
}
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.dispose();
--this._p._count === 0 && this._p._connectableSubscription.dispose();
}
};
return RefCountObservable;
}(ObservableBase));
var ConnectableObservable = Rx.ConnectableObservable = (function (__super__) {
inherits(ConnectableObservable, __super__);
function ConnectableObservable(source, subject) {
this.source = source;
this._connection = null;
this._source = source.asObservable();
this._subject = subject;
__super__.call(this);
}
function ConnectDisposable(parent, subscription) {
this._p = parent;
this._s = subscription;
}
ConnectDisposable.prototype.dispose = function () {
if (this._s) {
this._s.dispose();
this._s = null;
this._p._connection = null;
}
};
ConnectableObservable.prototype.connect = function () {
if (!this._connection) {
if (this._subject.isStopped) {
return disposableEmpty;
}
var subscription = this._source.subscribe(this._subject);
this._connection = new ConnectDisposable(this, subscription);
}
return this._connection;
};
ConnectableObservable.prototype._subscribe = function (o) {
return this._subject.subscribe(o);
};
ConnectableObservable.prototype.refCount = function () {
return new RefCountObservable(this);
};
return ConnectableObservable;
}(Observable));
return Rx;
}));
================================================
FILE: modules/rx-core-testing/package.json
================================================
{
"name": "rx-core-testing",
"title": "Reactive Extensions for JavaScript (RxJS) Core",
"description": "Core testing library for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.core.testing.js"
},
"browser": {
"index.js": "rx.core.testing.js"
},
"dependencies": {
"rx-core": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.core.testing.js"
}
================================================
FILE: modules/rx-core-testing/readme.md
================================================
# RxJS Core Testing Module #
The Reactive Extensions for JavaScript has a built-in mechanism for testing all operators which allows for mocking absolute and relative time with ease for use with `rx.core.js` and `rx.core.binding.js`
## Details ##
Files:
- [`rx.testing.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.testing.js)
NPM Packages:
- [`rx-core-testing`](https://www.npmjs.com/package/rx-core-testing)
NuGet Packages:
- _None_
File Dependencies:
- [`rx.core.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.core.js)
NuGet Dependencies:
- _None_
## Included Classes ##
### Core Objects
- [`Rx.Notification`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/notification.md)
### Schedulers
- [`Rx.TestScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/testscheduler.md)
- [`Rx.VirtualTimeScheduler`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/schedulers/virtualtimescheduler.md)
### Testing Classes
- [`Rx.ReactiveTest`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/reactivetest.md)
- [`Rx.Recorded`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/recorded.md)
- [`Rx.Subscription`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/testing/subscription.md)
================================================
FILE: modules/rx-core-testing/rx.core.testing.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.core'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx.core'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
notImplemented = Rx.helpers.notImplemented,
defaultComparer = Rx.helpers.defaultComparer = function (a, b) { return isEqual(a, b); };
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
return Rx;
}));
================================================
FILE: modules/rx-lite/package.json
================================================
{
"name": "rx-lite",
"title": "Reactive Extensions for JavaScript (RxJS) Lite",
"description": "Lightweight library for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.js"
},
"browser": {
"index.js": "rx.lite.js"
},
"dependencies": {},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.js"
}
================================================
FILE: modules/rx-lite/readme.md
================================================
# RxJS Lite Module #
The Reactive Extensions for JavaScript Lite version is a lightweight version of the Reactive Extensions for JavaScript which covers most of the day to day operators you might use all in a single library. Functionality such as bridging to events, promises, callbacks, Node.js-style callbacks, time-based operations and more are built right in. This comes with `rx.lite.js` which is for use in modern development environments such as > IE9 and server-side environments such as Node.js.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite
$ npm install -g rx-lite
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`catch | catchException`](../../doc/api/core/operators/catch.md)
- [`concat`](../../doc/api/core/operators/concat.md)
- [`create | createWithDisposable`](../../doc/api/core/operators/create.md)
- [`defer`](../../doc/api/core/operators/defer.md)
- [`empty`](../../doc/api/core/operators/empty.md)
- [`from`](../../doc/api/core/operators/from.md)
- [`fromArray`](../../doc/api/core/operators/fromarray.md)
- [`fromCallback`](../../doc/api/core/operators/fromcallback.md)
- [`fromEvent`](../../doc/api/core/operators/fromevent.md)
- [`fromEventPattern`](../../doc/api/core/operators/fromeventpattern.md)
- [`fromNodeCallback`](../../doc/api/core/operators/fromnodecallback.md)
- [`fromPromise`](../../doc/api/core/operators/frompromise.md)
- [`interval`](../../doc/api/core/operators/interval.md)
- [`just`](../../doc/api/core/operators/return.md)
- [`merge`](../../doc/api/core/operators/merge.md)
- [`mergeDelayError`](../../doc/api/core/operators/mergedelayerror.md)
- [`never`](../../doc/api/core/operators/never.md)
- [`of`](../../doc/api/core/operators/of.md)
- [`ofWithScheduler`](../../doc/api/core/operators/ofwithscheduler.md)
- [`range`](../../doc/api/core/operators/range.md)
- [`repeat`](../../doc/api/core/operators/repeat.md)
- [`return | returnValue`](../../doc/api/core/operators/return.md)
- [`throw | throwError | throwException`](../../doc/api/core/operators/throw.md)
- [`timer`](../../doc/api/core/operators/timer.md)
- [`zip`](../../doc/api/core/operators/zip.md)
- [`zipArray`](../../doc/api/core/operators/ziparray.md)
### `Observable Instance Methods`
- [`asObservable`](../../doc/api/core/operators/asobservable.md)
- [`catch | catchException`](../../doc/api/core/operators/catchproto.md)
- [`combineLatest`](../../doc/api/core/operators/combinelatest.md)
- [`concat`](../../doc/api/core/operators/concatproto.md)
- [`concatMap`](../../doc/api/core/operators/concatmap.md)
- [`connect`](../../doc/api/core/operators/connect.md)
- [`debounce`](../../doc/api/core/operators/debounce.md)
- [`defaultIfEmpty`](../../doc/api/core/operators/defaultifempty.md)
- [`delay`](../../doc/api/core/operators/delay.md)
- [`dematerialize`](../../doc/api/core/operators/dematerialize.md)
- [`distinctUntilChanged`](../../doc/api/core/operators/distinctuntilchanged.md)
- [`do | doAction`](../../doc/api/core/operators/do.md)
- [`doOnNext`](../../doc/api/core/operators/doonnext.md)
- [`doOnError`](../../doc/api/core/operators/doonerror.md)
- [`doOnCompleted`](../../doc/api/core/operators/dooncompleted.md)
- [`filter`](../../doc/api/core/operators/where.md)
- [`finally | finallyAction`](../../doc/api/core/operators/finally.md)
- [`flatMap`](../../doc/api/core/operators/selectmany.md)
- [`flatMapLatest`](../../doc/api/core/operators/flatmaplatest.md)
- [`ignoreElements`](../../doc/api/core/operators/ignoreelements.md)
- [`map`](../../doc/api/core/operators/select.md)
- [`merge`](../../doc/api/core/operators/mergeproto.md)
- [`mergeObservable | mergeAll`](../../doc/api/core/operators/mergeall.md)
- [`multicast`](../../doc/api/core/operators/multicast.md)
- [`publish`](../../doc/api/core/operators/publish.md)
- [`publishLast`](../../doc/api/core/operators/publishlast.md)
- [`publishValue`](../../doc/api/core/operators/publishvalue.md)
- [`refCount`](../../doc/api/core/operators/refcount.md)
- [`repeat`](../../doc/api/core/operators/repeat.md)
- [`replay`](../../doc/api/core/operators/replay.md)
- [`retry`](../../doc/api/core/operators/retry.md)
- [`retryWhen`](../../doc/api/core/operators/retrywhen.md)
- [`sample`](../../doc/api/core/operators/sample.md)
- [`scan`](../../doc/api/core/operators/scan.md)
- [`select`](../../doc/api/core/operators/select.md)
- [`selectConcat`](../../doc/api/core/operators/concatmap.md)
- [`selectMany`](../../doc/api/core/operators/selectmany.md)
- [`selectSwitch`](../../doc/api/core/operators/flatmaplatest.md)
- [`singleInstance`](../../doc/api/core/operators/singleinstance.md)
- [`skip`](../../doc/api/core/operators/skip.md)
- [`skipLast`](../../doc/api/core/operators/skiplast.md)
- [`skipUntil`](../../doc/api/core/operators/skipuntil.md)
- [`skipWhile`](../../doc/api/core/operators/skipwhile.md)
- [`startWith`](../../doc/api/core/operators/startwith.md)
- [`subscribe | forEach`](../../doc/api/core/operators/subscribe.md)
- [`subscribeOnNext`](../../doc/api/core/operators/subscribeonnext.md)
- [`subscribeOnError`](../../doc/api/core/operators/subscribeonerror.md)
- [`subscribeOnCompleted`](../../doc/api/core/operators/subscribeoncompleted.md)
- [`switch | switchLatest`](../../doc/api/core/operators/switch.md)
- [`take`](../../doc/api/core/operators/take.md)
- [`takeLast`](../../doc/api/core/operators/takelast.md)
- [`takeUntil`](../../doc/api/core/operators/takeuntil.md)
- [`takeWhile`](../../doc/api/core/operators/takewhile.md)
- [`tap`](../../doc/api/core/operators/do.md)
- [`tapOnNext`](../../doc/api/core/operators/doonnext.md)
- [`tapOnError`](../../doc/api/core/operators/doonerror.md)
- [`tapOnCompleted`](../../doc/api/core/operators/dooncompleted.md)
- [`throttle`](../../doc/api/core/operators/throttle.md)
- [`timeout`](../../doc/api/core/operators/timeout.md)
- [`timestamp`](../../doc/api/core/operators/timestamp.md)
- [`toArray`](../../doc/api/core/operators/toarray.md)
- [`transduce`](../../doc/api/core/operators/transduce.md)
- [`where`](../../doc/api/core/operators/where.md)
- [`withLatestFrom`](../../doc/api/core/operators/withlatestfrom.md)
- [`zip`](../../doc/api/core/operators/zipproto.md)
## Included Classes ##
### Core Objects
- [`Rx.Observer`](../../doc/api/core/observer.md)
- [`Rx.Notification`](../../doc/api/core/notification.md)
### Subjects
- [`Rx.AsyncSubject`](../../doc/api/subjects/asyncsubject.md)
- [`Rx.BehaviorSubject`](../../doc/api/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](../../doc/api/subjects/replaysubject.md)
- [`Rx.Subject`](../../doc/api/subjects/subject.md)
### Schedulers
- [`Rx.Scheduler`](../../doc/api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](../../doc/api/disposables/compositedisposable.md)
- [`Rx.Disposable`](../../doc/api/disposables/disposable.md)
- [`Rx.RefCountDisposable`](../../doc/api/disposables/refcountdisposable.md)
- [`Rx.SerialDisposable`](../../doc/api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](../../doc/api/disposables/singleassignmentdisposable.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite/rx.lite.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
var PausableObservable = (function (__super__) {
inherits(PausableObservable, __super__);
function PausableObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableObservable.prototype._subscribe = function (o) {
var conn = this.source.publish(),
subscription = conn.subscribe(o),
connection = disposableEmpty;
var pausable = this.pauser.startWith(!this.paused).distinctUntilChanged().subscribe(function (b) {
if (b) {
connection = conn.connect();
} else {
connection.dispose();
connection = disposableEmpty;
}
});
return new NAryDisposable([subscription, connection, pausable]);
};
PausableObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausable = function (pauser) {
return new PausableObservable(this, pauser);
};
function combineLatestSource(source, subject, resultSelector) {
return new AnonymousObservable(function (o) {
var hasValue = [false, false],
hasValueAll = false,
isDone = false,
values = new Array(2),
err;
function next(x, i) {
values[i] = x;
hasValue[i] = true;
if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
if (err) { return o.onError(err); }
var res = tryCatch(resultSelector).apply(null, values);
if (res === errorObj) { return o.onError(res.e); }
o.onNext(res);
}
isDone && values[1] && o.onCompleted();
}
return new BinaryDisposable(
source.subscribe(
function (x) {
next(x, 0);
},
function (e) {
if (values[1]) {
o.onError(e);
} else {
err = e;
}
},
function () {
isDone = true;
values[1] && o.onCompleted();
}),
subject.subscribe(
function (x) {
next(x, 1);
},
function (e) { o.onError(e); },
function () {
isDone = true;
next(true, 1);
})
);
}, source);
}
var PausableBufferedObservable = (function (__super__) {
inherits(PausableBufferedObservable, __super__);
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableBufferedObservable.prototype._subscribe = function (o) {
var q = [], previousShouldFire;
function drainQueue() { while (q.length > 0) { o.onNext(q.shift()); } }
var subscription =
combineLatestSource(
this.source,
this.pauser.startWith(!this.paused).distinctUntilChanged(),
function (data, shouldFire) {
return { data: data, shouldFire: shouldFire };
})
.subscribe(
function (results) {
if (previousShouldFire !== undefined && results.shouldFire !== previousShouldFire) {
previousShouldFire = results.shouldFire;
// change in shouldFire
if (results.shouldFire) { drainQueue(); }
} else {
previousShouldFire = results.shouldFire;
// new data
if (results.shouldFire) {
o.onNext(results.data);
} else {
q.push(results.data);
}
}
},
function (err) {
drainQueue();
o.onError(err);
},
function () {
drainQueue();
o.onCompleted();
}
);
return subscription;
};
PausableBufferedObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableBufferedObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableBufferedObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausableBuffered = function (pauser) {
return new PausableBufferedObservable(this, pauser);
};
var ControlledObservable = (function (__super__) {
inherits(ControlledObservable, __super__);
function ControlledObservable (source, enableQueue, scheduler) {
__super__.call(this);
this.subject = new ControlledSubject(enableQueue, scheduler);
this.source = source.multicast(this.subject).refCount();
}
ControlledObservable.prototype._subscribe = function (o) {
return this.source.subscribe(o);
};
ControlledObservable.prototype.request = function (numberOfItems) {
return this.subject.request(numberOfItems == null ? -1 : numberOfItems);
};
return ControlledObservable;
}(Observable));
var ControlledSubject = (function (__super__) {
inherits(ControlledSubject, __super__);
function ControlledSubject(enableQueue, scheduler) {
enableQueue == null && (enableQueue = true);
__super__.call(this);
this.subject = new Subject();
this.enableQueue = enableQueue;
this.queue = enableQueue ? [] : null;
this.requestedCount = 0;
this.requestedDisposable = null;
this.error = null;
this.hasFailed = false;
this.hasCompleted = false;
this.scheduler = scheduler || currentThreadScheduler;
}
addProperties(ControlledSubject.prototype, Observer, {
_subscribe: function (o) {
return this.subject.subscribe(o);
},
onCompleted: function () {
this.hasCompleted = true;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onCompleted();
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnCompleted());
}
},
onError: function (error) {
this.hasFailed = true;
this.error = error;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onError(error);
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnError(error));
}
},
onNext: function (value) {
if (this.requestedCount <= 0) {
this.enableQueue && this.queue.push(Notification.createOnNext(value));
} else {
(this.requestedCount-- === 0) && this.disposeCurrentRequest();
this.subject.onNext(value);
}
},
_processRequest: function (numberOfItems) {
if (this.enableQueue) {
while (this.queue.length > 0 && (numberOfItems > 0 || this.queue[0].kind !== 'N')) {
var first = this.queue.shift();
first.accept(this.subject);
if (first.kind === 'N') {
numberOfItems--;
} else {
this.disposeCurrentRequest();
this.queue = [];
}
}
}
return numberOfItems;
},
request: function (number) {
this.disposeCurrentRequest();
var self = this;
this.requestedDisposable = this.scheduler.schedule(number,
function(s, i) {
var remaining = self._processRequest(i);
var stopped = self.hasCompleted || self.hasFailed;
if (!stopped && remaining > 0) {
self.requestedCount = remaining;
return disposableCreate(function () {
self.requestedCount = 0;
});
// Scheduled item is still in progress. Return a new
// disposable to allow the request to be interrupted
// via dispose.
}
});
return this.requestedDisposable;
},
disposeCurrentRequest: function () {
if (this.requestedDisposable) {
this.requestedDisposable.dispose();
this.requestedDisposable = null;
}
}
});
return ControlledSubject;
}(Observable));
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
observableProto.controlled = function (enableQueue, scheduler) {
if (enableQueue && isScheduler(enableQueue)) {
scheduler = enableQueue;
enableQueue = true;
}
if (enableQueue == null) { enableQueue = true; }
return new ControlledObservable(this, enableQueue, scheduler);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: modules/rx-lite-aggregates/package.json
================================================
{
"name": "rx-lite-aggregates",
"title": "Reactive Extensions for JavaScript (RxJS) Aggregates",
"description": "Lightweight library with aggregate functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.aggregates.js"
},
"browser": {
"index.js": "rx.lite.aggregates.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.aggregates.js"
}
================================================
FILE: modules/rx-lite-aggregates/readme.md
================================================
# RxJS Aggregates Module #
The Reactive Extensions for JavaScript has a number of aggregation operators including those you might already know from the Array#extras and the upcoming ES6 standard such as `reduce`, `find` and `findIndex`. This module is used exclusively for aggregation operations used on finite observable sequences. In addition to the aforementioned operators, there are many useful operators such as `count`, `sum`, `average` and determining whether two sequences are equal via the `sequenceEqual` method. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-aggregates
$ npm install -g rx-lite-aggregates
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-aggregates');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Instance Methods`
- [`aggregate`](../../doc/api/core/operators/reduce.md)
- [`all`](../../doc/api/core/operators/every.md)
- [`any`](../../doc/api/core/operators/some.md)
- [`average`](../../doc/api/core/operators/average.md)
- [`includes`](../../doc/api/core/operators/includes.md)
- [`count`](../../doc/api/core/operators/count.md)
- [`elementAt`](../../doc/api/core/operators/elementat.md)
- [`elementAtOrDefault`](../../doc/api/core/operators/elementatordefault.md)
- [`every`](../../doc/api/core/operators/every.md)
- [`find`](../../doc/api/core/operators/find.md)
- [`findIndex`](../../doc/api/core/operators/findindex.md)
- [`first`](../../doc/api/core/operators/first.md)
- [`firstOrDefault`](../../doc/api/core/operators/firstordefault.md)
- [`indexOf`](../../doc/api/core/operators/indexof.md)
- [`isEmpty`](../../doc/api/core/operators/isempty.md)
- [`last`](../../doc/api/core/operators/last.md)
- [`lastOrDefault`](../../doc/api/core/operators/lastordefault.md)
- [`max`](../../doc/api/core/operators/max.md)
- [`maxBy`](../../doc/api/core/operators/maxby.md)
- [`min`](../../doc/api/core/operators/min.md)
- [`minBy`](../../doc/api/core/operators/minby.md)
- [`reduce`](../../doc/api/core/operators/reduce.md)
- [`sequenceEqual`](../../doc/api/core/operators/sequenceequal.md)
- [`single`](../../doc/api/core/operators/single.md)
- [`singleOrDefault`](../../doc/api/core/operators/singleordefault.md)
- [`some`](../../doc/api/core/operators/some.md)
- [`sum`](../../doc/api/core/operators/sum.md)
- [`toMap`](../../doc/api/core/operators/tomap.md)
- [`toSet`](../../doc/api/core/operators/toset.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-aggregates/rx.lite.aggregates.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
BinaryDisposable = Rx.BinaryDisposable,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
disposableEmpty = Rx.Disposable.empty,
helpers = Rx.helpers,
defaultComparer = helpers.defaultComparer,
identity = helpers.identity,
defaultSubComparer = helpers.defaultSubComparer,
isFunction = helpers.isFunction,
isPromise = helpers.isPromise,
isArrayLike = helpers.isArrayLike,
isIterable = helpers.isIterable,
inherits = Rx.internals.inherits,
observableFromPromise = Observable.fromPromise,
observableFrom = Observable.from,
bindCallback = Rx.internals.bindCallback,
EmptyError = Rx.EmptyError,
ObservableBase = Rx.ObservableBase,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var ExtremaByObservable = (function (__super__) {
inherits(ExtremaByObservable, __super__);
function ExtremaByObservable(source, k, c) {
this.source = source;
this._k = k;
this._c = c;
__super__.call(this);
}
ExtremaByObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ExtremaByObserver(o, this._k, this._c));
};
return ExtremaByObservable;
}(ObservableBase));
var ExtremaByObserver = (function (__super__) {
inherits(ExtremaByObserver, __super__);
function ExtremaByObserver(o, k, c) {
this._o = o;
this._k = k;
this._c = c;
this._v = null;
this._hv = false;
this._l = [];
__super__.call(this);
}
ExtremaByObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var comparison = 0;
if (!this._hv) {
this._hv = true;
this._v = key;
} else {
comparison = tryCatch(this._c)(key, this._v);
if (comparison === errorObj) { return this._o.onError(comparison.e); }
}
if (comparison > 0) {
this._v = key;
this._l = [];
}
if (comparison >= 0) { this._l.push(x); }
};
ExtremaByObserver.prototype.error = function (e) {
this._o.onError(e);
};
ExtremaByObserver.prototype.completed = function () {
this._o.onNext(this._l);
this._o.onCompleted();
};
return ExtremaByObserver;
}(AbstractObserver));
function firstOnly(x) {
if (x.length === 0) { throw new EmptyError(); }
return x[0];
}
var ReduceObservable = (function(__super__) {
inherits(ReduceObservable, __super__);
function ReduceObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ReduceObservable.prototype.subscribeCore = function(observer) {
return this.source.subscribe(new ReduceObserver(observer,this));
};
return ReduceObservable;
}(ObservableBase));
var ReduceObserver = (function (__super__) {
inherits(ReduceObserver, __super__);
function ReduceObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ReduceObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._i++;
};
ReduceObserver.prototype.error = function (e) {
this._o.onError(e);
};
ReduceObserver.prototype.completed = function () {
this._hv && this._o.onNext(this._a);
!this._hv && this._hs && this._o.onNext(this._s);
!this._hv && !this._hs && this._o.onError(new EmptyError());
this._o.onCompleted();
};
return ReduceObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
* For aggregation behavior with incremental intermediate results, see Observable.scan.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @param {Any} [seed] The initial accumulator value.
* @returns {Observable} An observable sequence containing a single element with the final accumulator value.
*/
observableProto.reduce = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ReduceObservable(this, accumulator, hasSeed, seed);
};
var SomeObservable = (function (__super__) {
inherits(SomeObservable, __super__);
function SomeObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SomeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SomeObserver(o, this._fn, this.source));
};
return SomeObservable;
}(ObservableBase));
var SomeObserver = (function (__super__) {
inherits(SomeObserver, __super__);
function SomeObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
SomeObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (Boolean(result)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
SomeObserver.prototype.error = function (e) { this._o.onError(e); };
SomeObserver.prototype.completed = function () {
this._o.onNext(false);
this._o.onCompleted();
};
return SomeObserver;
}(AbstractObserver));
/**
* Determines whether any element of an observable sequence satisfies a condition if present, else if any items are in the sequence.
* @param {Function} [predicate] A function to test each element for a condition.
* @returns {Observable} An observable sequence containing a single element determining whether any elements in the source sequence pass the test in the specified predicate if given, else if any items are in the sequence.
*/
observableProto.some = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SomeObservable(this, fn);
};
var IsEmptyObservable = (function (__super__) {
inherits(IsEmptyObservable, __super__);
function IsEmptyObservable(source) {
this.source = source;
__super__.call(this);
}
IsEmptyObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new IsEmptyObserver(o));
};
return IsEmptyObservable;
}(ObservableBase));
var IsEmptyObserver = (function(__super__) {
inherits(IsEmptyObserver, __super__);
function IsEmptyObserver(o) {
this._o = o;
__super__.call(this);
}
IsEmptyObserver.prototype.next = function () {
this._o.onNext(false);
this._o.onCompleted();
};
IsEmptyObserver.prototype.error = function (e) { this._o.onError(e); };
IsEmptyObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return IsEmptyObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence is empty.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence is empty.
*/
observableProto.isEmpty = function () {
return new IsEmptyObservable(this);
};
var EveryObservable = (function (__super__) {
inherits(EveryObservable, __super__);
function EveryObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
EveryObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new EveryObserver(o, this._fn, this.source));
};
return EveryObservable;
}(ObservableBase));
var EveryObserver = (function (__super__) {
inherits(EveryObserver, __super__);
function EveryObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
EveryObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (!Boolean(result)) {
this._o.onNext(false);
this._o.onCompleted();
}
};
EveryObserver.prototype.error = function (e) { this._o.onError(e); };
EveryObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return EveryObserver;
}(AbstractObserver));
/**
* Determines whether all elements of an observable sequence satisfy a condition.
* @param {Function} [predicate] A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.
*/
observableProto.every = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new EveryObservable(this, fn);
};
var IncludesObservable = (function (__super__) {
inherits(IncludesObservable, __super__);
function IncludesObservable(source, elem, idx) {
var n = +idx || 0;
Math.abs(n) === Infinity && (n = 0);
this.source = source;
this._elem = elem;
this._n = n;
__super__.call(this);
}
IncludesObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(false);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IncludesObserver(o, this._elem, this._n));
};
return IncludesObservable;
}(ObservableBase));
var IncludesObserver = (function (__super__) {
inherits(IncludesObserver, __super__);
function IncludesObserver(o, elem, n) {
this._o = o;
this._elem = elem;
this._n = n;
this._i = 0;
__super__.call(this);
}
function comparer(a, b) {
return (a === 0 && b === 0) || (a === b || (isNaN(a) && isNaN(b)));
}
IncludesObserver.prototype.next = function (x) {
if (this._i++ >= this._n && comparer(x, this._elem)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
IncludesObserver.prototype.error = function (e) { this._o.onError(e); };
IncludesObserver.prototype.completed = function () { this._o.onNext(false); this._o.onCompleted(); };
return IncludesObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence includes a specified element with an optional equality comparer.
* @param searchElement The value to locate in the source sequence.
* @param {Number} [fromIndex] An equality comparer to compare elements.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence includes an element that has the specified value from the given index.
*/
observableProto.includes = function (searchElement, fromIndex) {
return new IncludesObservable(this, searchElement, fromIndex);
};
var CountObservable = (function (__super__) {
inherits(CountObservable, __super__);
function CountObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
CountObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new CountObserver(o, this._fn, this.source));
};
return CountObservable;
}(ObservableBase));
var CountObserver = (function (__super__) {
inherits(CountObserver, __super__);
function CountObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
CountObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
Boolean(result) && (this._c++);
} else {
this._c++;
}
};
CountObserver.prototype.error = function (e) { this._o.onError(e); };
CountObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return CountObserver;
}(AbstractObserver));
/**
* Returns an observable sequence containing a value that represents how many elements in the specified observable sequence satisfy a condition if provided, else the count of items.
* @example
* res = source.count();
* res = source.count(function (x) { return x > 3; });
* @param {Function} [predicate]A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function if provided, else the count of items in the sequence.
*/
observableProto.count = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new CountObservable(this, fn);
};
var IndexOfObservable = (function (__super__) {
inherits(IndexOfObservable, __super__);
function IndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
IndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IndexOfObserver(o, this._e, this._n));
};
return IndexOfObservable;
}(ObservableBase));
var IndexOfObserver = (function (__super__) {
inherits(IndexOfObserver, __super__);
function IndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._i = 0;
__super__.call(this);
}
IndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._o.onNext(this._i);
this._o.onCompleted();
}
this._i++;
};
IndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
IndexOfObserver.prototype.completed = function () { this._o.onNext(-1); this._o.onCompleted(); };
return IndexOfObserver;
}(AbstractObserver));
/**
* Returns the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.indexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new IndexOfObservable(this, searchElement, n);
};
var SumObservable = (function (__super__) {
inherits(SumObservable, __super__);
function SumObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SumObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SumObserver(o, this._fn, this.source));
};
return SumObservable;
}(ObservableBase));
var SumObserver = (function (__super__) {
inherits(SumObserver, __super__);
function SumObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
SumObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
this._c += result;
} else {
this._c += x;
}
};
SumObserver.prototype.error = function (e) { this._o.onError(e); };
SumObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return SumObserver;
}(AbstractObserver));
/**
* Computes the sum of a sequence of values that are obtained by invoking an optional transform function on each element of the input sequence, else if not specified computes the sum on each item in the sequence.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the sum of the values in the source sequence.
*/
observableProto.sum = function (keySelector, thisArg) {
var fn = bindCallback(keySelector, thisArg, 3);
return new SumObservable(this, fn);
};
/**
* Returns the elements in an observable sequence with the minimum key value according to the specified comparer.
* @example
* var res = source.minBy(function (x) { return x.value; });
* var res = source.minBy(function (x) { return x.value; }, function (x, y) { return x - y; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a minimum key value.
*/
observableProto.minBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, function (x, y) { return comparer(x, y) * -1; });
};
/**
* Returns the minimum element in an observable sequence according to the optional comparer else a default greater than less than check.
* @example
* var res = source.min();
* var res = source.min(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the minimum element in the source sequence.
*/
observableProto.min = function (comparer) {
return this.minBy(identity, comparer).map(firstOnly);
};
/**
* Returns the elements in an observable sequence with the maximum key value according to the specified comparer.
* @example
* var res = source.maxBy(function (x) { return x.value; });
* var res = source.maxBy(function (x) { return x.value; }, function (x, y) { return x - y;; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a maximum key value.
*/
observableProto.maxBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, comparer);
};
/**
* Returns the maximum value in an observable sequence according to the specified comparer.
* @example
* var res = source.max();
* var res = source.max(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the maximum element in the source sequence.
*/
observableProto.max = function (comparer) {
return this.maxBy(identity, comparer).map(firstOnly);
};
var AverageObservable = (function (__super__) {
inherits(AverageObservable, __super__);
function AverageObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
AverageObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new AverageObserver(o, this._fn, this.source));
};
return AverageObservable;
}(ObservableBase));
var AverageObserver = (function(__super__) {
inherits(AverageObserver, __super__);
function AverageObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._c = 0;
this._t = 0;
__super__.call(this);
}
AverageObserver.prototype.next = function (x) {
if(this._fn) {
var r = tryCatch(this._fn)(x, this._c++, this._s);
if (r === errorObj) { return this._o.onError(r.e); }
this._t += r;
} else {
this._c++;
this._t += x;
}
};
AverageObserver.prototype.error = function (e) { this._o.onError(e); };
AverageObserver.prototype.completed = function () {
if (this._c === 0) { return this._o.onError(new EmptyError()); }
this._o.onNext(this._t / this._c);
this._o.onCompleted();
};
return AverageObserver;
}(AbstractObserver));
/**
* Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the average of the sequence of values.
*/
observableProto.average = function (keySelector, thisArg) {
var source = this, fn;
if (isFunction(keySelector)) {
fn = bindCallback(keySelector, thisArg, 3);
}
return new AverageObservable(source, fn);
};
/**
* Determines whether two sequences are equal by comparing the elements pairwise using a specified equality comparer.
*
* @example
* var res = res = source.sequenceEqual([1,2,3]);
* var res = res = source.sequenceEqual([{ value: 42 }], function (x, y) { return x.value === y.value; });
* 3 - res = source.sequenceEqual(Rx.Observable.returnValue(42));
* 4 - res = source.sequenceEqual(Rx.Observable.returnValue({ value: 42 }), function (x, y) { return x.value === y.value; });
* @param {Observable} second Second observable sequence or array to compare.
* @param {Function} [comparer] Comparer used to compare elements of both sequences.
* @returns {Observable} An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.
*/
observableProto.sequenceEqual = function (second, comparer) {
var first = this;
comparer || (comparer = defaultComparer);
return new AnonymousObservable(function (o) {
var donel = false, doner = false, ql = [], qr = [];
var subscription1 = first.subscribe(function (x) {
if (qr.length > 0) {
var v = qr.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (doner) {
o.onNext(false);
o.onCompleted();
} else {
ql.push(x);
}
}, function(e) { o.onError(e); }, function () {
donel = true;
if (ql.length === 0) {
if (qr.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (doner) {
o.onNext(true);
o.onCompleted();
}
}
});
(isArrayLike(second) || isIterable(second)) && (second = observableFrom(second));
isPromise(second) && (second = observableFromPromise(second));
var subscription2 = second.subscribe(function (x) {
if (ql.length > 0) {
var v = ql.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (donel) {
o.onNext(false);
o.onCompleted();
} else {
qr.push(x);
}
}, function(e) { o.onError(e); }, function () {
doner = true;
if (qr.length === 0) {
if (ql.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (donel) {
o.onNext(true);
o.onCompleted();
}
}
});
return new BinaryDisposable(subscription1, subscription2);
}, first);
};
var ElementAtObservable = (function (__super__) {
inherits(ElementAtObservable, __super__);
function ElementAtObservable(source, i, d) {
this.source = source;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ElementAtObserver(o, this._i, this._d));
};
return ElementAtObservable;
}(ObservableBase));
var ElementAtObserver = (function (__super__) {
inherits(ElementAtObserver, __super__);
function ElementAtObserver(o, i, d) {
this._o = o;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObserver.prototype.next = function (x) {
if (this._i-- === 0) {
this._o.onNext(x);
this._o.onCompleted();
}
};
ElementAtObserver.prototype.error = function (e) { this._o.onError(e); };
ElementAtObserver.prototype.completed = function () {
if (this._d === undefined) {
this._o.onError(new ArgumentOutOfRangeError());
} else {
this._o.onNext(this._d);
this._o.onCompleted();
}
};
return ElementAtObserver;
}(AbstractObserver));
/**
* Returns the element at a specified index in a sequence or default value if not found.
* @param {Number} index The zero-based index of the element to retrieve.
* @param {Any} [defaultValue] The default value to use if elementAt does not find a value.
* @returns {Observable} An observable sequence that produces the element at the specified position in the source sequence.
*/
observableProto.elementAt = function (index, defaultValue) {
if (index < 0) { throw new ArgumentOutOfRangeError(); }
return new ElementAtObservable(this, index, defaultValue);
};
var SingleObserver = (function(__super__) {
inherits(SingleObserver, __super__);
function SingleObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
SingleObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
if (this._hv) {
return this._o.onError(new Error('Sequence contains more than one matching element'));
}
this._hv = true;
this._v = x;
}
};
SingleObserver.prototype.error = function (e) { this._o.onError(e); };
SingleObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return SingleObserver;
}(AbstractObserver));
/**
* Returns the only element of an observable sequence that satisfies the condition in the optional predicate, and reports an exception if there is not exactly one element in the observable sequence.
* @returns {Observable} Sequence containing the single element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.single = function (predicate, thisArg) {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new AnonymousObservable(function (o) {
return source.subscribe(new SingleObserver(o, obj, source));
}, source);
};
var FirstObservable = (function (__super__) {
inherits(FirstObservable, __super__);
function FirstObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
FirstObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FirstObserver(o, this._obj, this.source));
};
return FirstObservable;
}(ObservableBase));
var FirstObserver = (function(__super__) {
inherits(FirstObserver, __super__);
function FirstObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
__super__.call(this);
}
FirstObserver.prototype.next = function (x) {
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
if (Boolean(res)) {
this._o.onNext(x);
this._o.onCompleted();
}
} else if (!this._obj.predicate) {
this._o.onNext(x);
this._o.onCompleted();
}
};
FirstObserver.prototype.error = function (e) { this._o.onError(e); };
FirstObserver.prototype.completed = function () {
if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return FirstObserver;
}(AbstractObserver));
/**
* Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence.
* @returns {Observable} Sequence containing the first element in the observable sequence that satisfies the condition in the predicate if provided, else the first item in the sequence.
*/
observableProto.first = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new FirstObservable(this, obj);
};
var LastObservable = (function (__super__) {
inherits(LastObservable, __super__);
function LastObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
LastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new LastObserver(o, this._obj, this.source));
};
return LastObservable;
}(ObservableBase));
var LastObserver = (function(__super__) {
inherits(LastObserver, __super__);
function LastObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
LastObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
this._hv = true;
this._v = x;
}
};
LastObserver.prototype.error = function (e) { this._o.onError(e); };
LastObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return LastObserver;
}(AbstractObserver));
/**
* Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element.
* @returns {Observable} Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.last = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new LastObservable(this, obj);
};
var FindValueObserver = (function(__super__) {
inherits(FindValueObserver, __super__);
function FindValueObserver(observer, source, callback, yieldIndex) {
this._o = observer;
this._s = source;
this._cb = callback;
this._y = yieldIndex;
this._i = 0;
__super__.call(this);
}
FindValueObserver.prototype.next = function (x) {
var shouldRun = tryCatch(this._cb)(x, this._i, this._s);
if (shouldRun === errorObj) { return this._o.onError(shouldRun.e); }
if (shouldRun) {
this._o.onNext(this._y ? this._i : x);
this._o.onCompleted();
} else {
this._i++;
}
};
FindValueObserver.prototype.error = function (e) {
this._o.onError(e);
};
FindValueObserver.prototype.completed = function () {
this._y && this._o.onNext(-1);
this._o.onCompleted();
};
return FindValueObserver;
}(AbstractObserver));
function findValue (source, predicate, thisArg, yieldIndex) {
var callback = bindCallback(predicate, thisArg, 3);
return new AnonymousObservable(function (o) {
return source.subscribe(new FindValueObserver(o, source, callback, yieldIndex));
}, source);
}
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the first element that matches the conditions defined by the specified predicate, if found; otherwise, undefined.
*/
observableProto.find = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, false);
};
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns
* an Observable sequence with the zero-based index of the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
*/
observableProto.findIndex = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, true);
};
var ToSetObservable = (function (__super__) {
inherits(ToSetObservable, __super__);
function ToSetObservable(source) {
this.source = source;
__super__.call(this);
}
ToSetObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToSetObserver(o));
};
return ToSetObservable;
}(ObservableBase));
var ToSetObserver = (function (__super__) {
inherits(ToSetObserver, __super__);
function ToSetObserver(o) {
this._o = o;
this._s = new root.Set();
__super__.call(this);
}
ToSetObserver.prototype.next = function (x) {
this._s.add(x);
};
ToSetObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToSetObserver.prototype.completed = function () {
this._o.onNext(this._s);
this._o.onCompleted();
};
return ToSetObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Set if it exists.
* @returns {Observable} An observable sequence with a single value of a Set containing the values from the observable sequence.
*/
observableProto.toSet = function () {
if (typeof root.Set === 'undefined') { throw new TypeError(); }
return new ToSetObservable(this);
};
var ToMapObservable = (function (__super__) {
inherits(ToMapObservable, __super__);
function ToMapObservable(source, k, e) {
this.source = source;
this._k = k;
this._e = e;
__super__.call(this);
}
ToMapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToMapObserver(o, this._k, this._e));
};
return ToMapObservable;
}(ObservableBase));
var ToMapObserver = (function (__super__) {
inherits(ToMapObserver, __super__);
function ToMapObserver(o, k, e) {
this._o = o;
this._k = k;
this._e = e;
this._m = new root.Map();
__super__.call(this);
}
ToMapObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var elem = x;
if (this._e) {
elem = tryCatch(this._e)(x);
if (elem === errorObj) { return this._o.onError(elem.e); }
}
this._m.set(key, elem);
};
ToMapObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToMapObserver.prototype.completed = function () {
this._o.onNext(this._m);
this._o.onCompleted();
};
return ToMapObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Map if it exists.
* @param {Function} keySelector A function which produces the key for the Map.
* @param {Function} [elementSelector] An optional function which produces the element for the Map. If not present, defaults to the value from the observable sequence.
* @returns {Observable} An observable sequence with a single value of a Map containing the values from the observable sequence.
*/
observableProto.toMap = function (keySelector, elementSelector) {
if (typeof root.Map === 'undefined') { throw new TypeError(); }
return new ToMapObservable(this, keySelector, elementSelector);
};
var SliceObservable = (function (__super__) {
inherits(SliceObservable, __super__);
function SliceObservable(source, b, e) {
this.source = source;
this._b = b;
this._e = e;
__super__.call(this);
}
SliceObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SliceObserver(o, this._b, this._e));
};
return SliceObservable;
}(ObservableBase));
var SliceObserver = (function (__super__) {
inherits(SliceObserver, __super__);
function SliceObserver(o, b, e) {
this._o = o;
this._b = b;
this._e = e;
this._i = 0;
__super__.call(this);
}
SliceObserver.prototype.next = function (x) {
if (this._i >= this._b) {
if (this._e === this._i) {
this._o.onCompleted();
} else {
this._o.onNext(x);
}
}
this._i++;
};
SliceObserver.prototype.error = function (e) { this._o.onError(e); };
SliceObserver.prototype.completed = function () { this._o.onCompleted(); };
return SliceObserver;
}(AbstractObserver));
/*
* The slice() method returns a shallow copy of a portion of an Observable into a new Observable object.
* Unlike the array version, this does not support negative numbers for being or end.
* @param {Number} [begin] Zero-based index at which to begin extraction. If omitted, this will default to zero.
* @param {Number} [end] Zero-based index at which to end extraction. slice extracts up to but not including end.
* If omitted, this will emit the rest of the Observable object.
* @returns {Observable} A shallow copy of a portion of an Observable into a new Observable object.
*/
observableProto.slice = function (begin, end) {
var start = begin || 0;
if (start < 0) { throw new Rx.ArgumentOutOfRangeError(); }
if (typeof end === 'number' && end < start) {
throw new Rx.ArgumentOutOfRangeError();
}
return new SliceObservable(this, start, end);
};
var LastIndexOfObservable = (function (__super__) {
inherits(LastIndexOfObservable, __super__);
function LastIndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
LastIndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new LastIndexOfObserver(o, this._e, this._n));
};
return LastIndexOfObservable;
}(ObservableBase));
var LastIndexOfObserver = (function (__super__) {
inherits(LastIndexOfObserver, __super__);
function LastIndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._v = 0;
this._hv = false;
this._i = 0;
__super__.call(this);
}
LastIndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._hv = true;
this._v = this._i;
}
this._i++;
};
LastIndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
LastIndexOfObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
} else {
this._o.onNext(-1);
}
this._o.onCompleted();
};
return LastIndexOfObserver;
}(AbstractObserver));
/**
* Returns the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.lastIndexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new LastIndexOfObservable(this, searchElement, n);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-aggregates-compat/package.json
================================================
{
"name": "rx-lite-aggregates-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Aggregates",
"description": "Lightweight older browser compatible library with aggregate functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.aggregates.compat.js"
},
"browser": {
"index.js": "rx.lite.aggregates.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.aggregates.compat.js"
}
================================================
FILE: modules/rx-lite-aggregates-compat/readme.md
================================================
# RxJS Aggregates Compat Module #
The Reactive Extensions for JavaScript has a number of aggregation operators including those you might already know from the Array#extras and the upcoming ES6 standard such as `reduce`, `find` and `findIndex`. This module is used exclusively for aggregation operations used on finite observable sequences. In addition to the aforementioned operators, there are many useful operators such as `count`, `sum`, `average` and determining whether two sequences are equal via the `sequenceEqual` method. This requires `rx.lite.compat.js` from the [`rx-lite-compat`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-aggregates-compat
$ npm install -g rx-lite-aggregates-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-aggregates-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Instance Methods`
- [`aggregate`](../../doc/api/core/operators/reduce.md)
- [`all`](../../doc/api/core/operators/every.md)
- [`any`](../../doc/api/core/operators/some.md)
- [`average`](../../doc/api/core/operators/average.md)
- [`includes`](../../doc/api/core/operators/includes.md)
- [`count`](../../doc/api/core/operators/count.md)
- [`elementAt`](../../doc/api/core/operators/elementat.md)
- [`elementAtOrDefault`](../../doc/api/core/operators/elementatordefault.md)
- [`every`](../../doc/api/core/operators/every.md)
- [`find`](../../doc/api/core/operators/find.md)
- [`findIndex`](../../doc/api/core/operators/findindex.md)
- [`first`](../../doc/api/core/operators/first.md)
- [`firstOrDefault`](../../doc/api/core/operators/firstordefault.md)
- [`indexOf`](../../doc/api/core/operators/indexof.md)
- [`isEmpty`](../../doc/api/core/operators/isempty.md)
- [`last`](../../doc/api/core/operators/last.md)
- [`lastOrDefault`](../../doc/api/core/operators/lastordefault.md)
- [`max`](../../doc/api/core/operators/max.md)
- [`maxBy`](../../doc/api/core/operators/maxby.md)
- [`min`](../../doc/api/core/operators/min.md)
- [`minBy`](../../doc/api/core/operators/minby.md)
- [`reduce`](../../doc/api/core/operators/reduce.md)
- [`sequenceEqual`](../../doc/api/core/operators/sequenceequal.md)
- [`single`](../../doc/api/core/operators/single.md)
- [`singleOrDefault`](../../doc/api/core/operators/singleordefault.md)
- [`some`](../../doc/api/core/operators/some.md)
- [`sum`](../../doc/api/core/operators/sum.md)
- [`toMap`](../../doc/api/core/operators/tomap.md)
- [`toSet`](../../doc/api/core/operators/toset.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-aggregates-compat/rx.lite.aggregates.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
BinaryDisposable = Rx.BinaryDisposable,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
disposableEmpty = Rx.Disposable.empty,
helpers = Rx.helpers,
defaultComparer = helpers.defaultComparer,
identity = helpers.identity,
defaultSubComparer = helpers.defaultSubComparer,
isFunction = helpers.isFunction,
isPromise = helpers.isPromise,
isArrayLike = helpers.isArrayLike,
isIterable = helpers.isIterable,
inherits = Rx.internals.inherits,
observableFromPromise = Observable.fromPromise,
observableFrom = Observable.from,
bindCallback = Rx.internals.bindCallback,
EmptyError = Rx.EmptyError,
ObservableBase = Rx.ObservableBase,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var ExtremaByObservable = (function (__super__) {
inherits(ExtremaByObservable, __super__);
function ExtremaByObservable(source, k, c) {
this.source = source;
this._k = k;
this._c = c;
__super__.call(this);
}
ExtremaByObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ExtremaByObserver(o, this._k, this._c));
};
return ExtremaByObservable;
}(ObservableBase));
var ExtremaByObserver = (function (__super__) {
inherits(ExtremaByObserver, __super__);
function ExtremaByObserver(o, k, c) {
this._o = o;
this._k = k;
this._c = c;
this._v = null;
this._hv = false;
this._l = [];
__super__.call(this);
}
ExtremaByObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var comparison = 0;
if (!this._hv) {
this._hv = true;
this._v = key;
} else {
comparison = tryCatch(this._c)(key, this._v);
if (comparison === errorObj) { return this._o.onError(comparison.e); }
}
if (comparison > 0) {
this._v = key;
this._l = [];
}
if (comparison >= 0) { this._l.push(x); }
};
ExtremaByObserver.prototype.error = function (e) {
this._o.onError(e);
};
ExtremaByObserver.prototype.completed = function () {
this._o.onNext(this._l);
this._o.onCompleted();
};
return ExtremaByObserver;
}(AbstractObserver));
function firstOnly(x) {
if (x.length === 0) { throw new EmptyError(); }
return x[0];
}
var ReduceObservable = (function(__super__) {
inherits(ReduceObservable, __super__);
function ReduceObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ReduceObservable.prototype.subscribeCore = function(observer) {
return this.source.subscribe(new ReduceObserver(observer,this));
};
return ReduceObservable;
}(ObservableBase));
var ReduceObserver = (function (__super__) {
inherits(ReduceObserver, __super__);
function ReduceObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ReduceObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._i++;
};
ReduceObserver.prototype.error = function (e) {
this._o.onError(e);
};
ReduceObserver.prototype.completed = function () {
this._hv && this._o.onNext(this._a);
!this._hv && this._hs && this._o.onNext(this._s);
!this._hv && !this._hs && this._o.onError(new EmptyError());
this._o.onCompleted();
};
return ReduceObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
* For aggregation behavior with incremental intermediate results, see Observable.scan.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @param {Any} [seed] The initial accumulator value.
* @returns {Observable} An observable sequence containing a single element with the final accumulator value.
*/
observableProto.reduce = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ReduceObservable(this, accumulator, hasSeed, seed);
};
var SomeObservable = (function (__super__) {
inherits(SomeObservable, __super__);
function SomeObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SomeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SomeObserver(o, this._fn, this.source));
};
return SomeObservable;
}(ObservableBase));
var SomeObserver = (function (__super__) {
inherits(SomeObserver, __super__);
function SomeObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
SomeObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (Boolean(result)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
SomeObserver.prototype.error = function (e) { this._o.onError(e); };
SomeObserver.prototype.completed = function () {
this._o.onNext(false);
this._o.onCompleted();
};
return SomeObserver;
}(AbstractObserver));
/**
* Determines whether any element of an observable sequence satisfies a condition if present, else if any items are in the sequence.
* @param {Function} [predicate] A function to test each element for a condition.
* @returns {Observable} An observable sequence containing a single element determining whether any elements in the source sequence pass the test in the specified predicate if given, else if any items are in the sequence.
*/
observableProto.some = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SomeObservable(this, fn);
};
var IsEmptyObservable = (function (__super__) {
inherits(IsEmptyObservable, __super__);
function IsEmptyObservable(source) {
this.source = source;
__super__.call(this);
}
IsEmptyObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new IsEmptyObserver(o));
};
return IsEmptyObservable;
}(ObservableBase));
var IsEmptyObserver = (function(__super__) {
inherits(IsEmptyObserver, __super__);
function IsEmptyObserver(o) {
this._o = o;
__super__.call(this);
}
IsEmptyObserver.prototype.next = function () {
this._o.onNext(false);
this._o.onCompleted();
};
IsEmptyObserver.prototype.error = function (e) { this._o.onError(e); };
IsEmptyObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return IsEmptyObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence is empty.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence is empty.
*/
observableProto.isEmpty = function () {
return new IsEmptyObservable(this);
};
var EveryObservable = (function (__super__) {
inherits(EveryObservable, __super__);
function EveryObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
EveryObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new EveryObserver(o, this._fn, this.source));
};
return EveryObservable;
}(ObservableBase));
var EveryObserver = (function (__super__) {
inherits(EveryObserver, __super__);
function EveryObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
EveryObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (!Boolean(result)) {
this._o.onNext(false);
this._o.onCompleted();
}
};
EveryObserver.prototype.error = function (e) { this._o.onError(e); };
EveryObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return EveryObserver;
}(AbstractObserver));
/**
* Determines whether all elements of an observable sequence satisfy a condition.
* @param {Function} [predicate] A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.
*/
observableProto.every = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new EveryObservable(this, fn);
};
var IncludesObservable = (function (__super__) {
inherits(IncludesObservable, __super__);
function IncludesObservable(source, elem, idx) {
var n = +idx || 0;
Math.abs(n) === Infinity && (n = 0);
this.source = source;
this._elem = elem;
this._n = n;
__super__.call(this);
}
IncludesObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(false);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IncludesObserver(o, this._elem, this._n));
};
return IncludesObservable;
}(ObservableBase));
var IncludesObserver = (function (__super__) {
inherits(IncludesObserver, __super__);
function IncludesObserver(o, elem, n) {
this._o = o;
this._elem = elem;
this._n = n;
this._i = 0;
__super__.call(this);
}
function comparer(a, b) {
return (a === 0 && b === 0) || (a === b || (isNaN(a) && isNaN(b)));
}
IncludesObserver.prototype.next = function (x) {
if (this._i++ >= this._n && comparer(x, this._elem)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
IncludesObserver.prototype.error = function (e) { this._o.onError(e); };
IncludesObserver.prototype.completed = function () { this._o.onNext(false); this._o.onCompleted(); };
return IncludesObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence includes a specified element with an optional equality comparer.
* @param searchElement The value to locate in the source sequence.
* @param {Number} [fromIndex] An equality comparer to compare elements.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence includes an element that has the specified value from the given index.
*/
observableProto.includes = function (searchElement, fromIndex) {
return new IncludesObservable(this, searchElement, fromIndex);
};
var CountObservable = (function (__super__) {
inherits(CountObservable, __super__);
function CountObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
CountObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new CountObserver(o, this._fn, this.source));
};
return CountObservable;
}(ObservableBase));
var CountObserver = (function (__super__) {
inherits(CountObserver, __super__);
function CountObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
CountObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
Boolean(result) && (this._c++);
} else {
this._c++;
}
};
CountObserver.prototype.error = function (e) { this._o.onError(e); };
CountObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return CountObserver;
}(AbstractObserver));
/**
* Returns an observable sequence containing a value that represents how many elements in the specified observable sequence satisfy a condition if provided, else the count of items.
* @example
* res = source.count();
* res = source.count(function (x) { return x > 3; });
* @param {Function} [predicate]A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function if provided, else the count of items in the sequence.
*/
observableProto.count = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new CountObservable(this, fn);
};
var IndexOfObservable = (function (__super__) {
inherits(IndexOfObservable, __super__);
function IndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
IndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IndexOfObserver(o, this._e, this._n));
};
return IndexOfObservable;
}(ObservableBase));
var IndexOfObserver = (function (__super__) {
inherits(IndexOfObserver, __super__);
function IndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._i = 0;
__super__.call(this);
}
IndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._o.onNext(this._i);
this._o.onCompleted();
}
this._i++;
};
IndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
IndexOfObserver.prototype.completed = function () { this._o.onNext(-1); this._o.onCompleted(); };
return IndexOfObserver;
}(AbstractObserver));
/**
* Returns the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.indexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new IndexOfObservable(this, searchElement, n);
};
var SumObservable = (function (__super__) {
inherits(SumObservable, __super__);
function SumObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SumObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SumObserver(o, this._fn, this.source));
};
return SumObservable;
}(ObservableBase));
var SumObserver = (function (__super__) {
inherits(SumObserver, __super__);
function SumObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
SumObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
this._c += result;
} else {
this._c += x;
}
};
SumObserver.prototype.error = function (e) { this._o.onError(e); };
SumObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return SumObserver;
}(AbstractObserver));
/**
* Computes the sum of a sequence of values that are obtained by invoking an optional transform function on each element of the input sequence, else if not specified computes the sum on each item in the sequence.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the sum of the values in the source sequence.
*/
observableProto.sum = function (keySelector, thisArg) {
var fn = bindCallback(keySelector, thisArg, 3);
return new SumObservable(this, fn);
};
/**
* Returns the elements in an observable sequence with the minimum key value according to the specified comparer.
* @example
* var res = source.minBy(function (x) { return x.value; });
* var res = source.minBy(function (x) { return x.value; }, function (x, y) { return x - y; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a minimum key value.
*/
observableProto.minBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, function (x, y) { return comparer(x, y) * -1; });
};
/**
* Returns the minimum element in an observable sequence according to the optional comparer else a default greater than less than check.
* @example
* var res = source.min();
* var res = source.min(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the minimum element in the source sequence.
*/
observableProto.min = function (comparer) {
return this.minBy(identity, comparer).map(firstOnly);
};
/**
* Returns the elements in an observable sequence with the maximum key value according to the specified comparer.
* @example
* var res = source.maxBy(function (x) { return x.value; });
* var res = source.maxBy(function (x) { return x.value; }, function (x, y) { return x - y;; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a maximum key value.
*/
observableProto.maxBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, comparer);
};
/**
* Returns the maximum value in an observable sequence according to the specified comparer.
* @example
* var res = source.max();
* var res = source.max(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the maximum element in the source sequence.
*/
observableProto.max = function (comparer) {
return this.maxBy(identity, comparer).map(firstOnly);
};
var AverageObservable = (function (__super__) {
inherits(AverageObservable, __super__);
function AverageObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
AverageObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new AverageObserver(o, this._fn, this.source));
};
return AverageObservable;
}(ObservableBase));
var AverageObserver = (function(__super__) {
inherits(AverageObserver, __super__);
function AverageObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._c = 0;
this._t = 0;
__super__.call(this);
}
AverageObserver.prototype.next = function (x) {
if(this._fn) {
var r = tryCatch(this._fn)(x, this._c++, this._s);
if (r === errorObj) { return this._o.onError(r.e); }
this._t += r;
} else {
this._c++;
this._t += x;
}
};
AverageObserver.prototype.error = function (e) { this._o.onError(e); };
AverageObserver.prototype.completed = function () {
if (this._c === 0) { return this._o.onError(new EmptyError()); }
this._o.onNext(this._t / this._c);
this._o.onCompleted();
};
return AverageObserver;
}(AbstractObserver));
/**
* Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the average of the sequence of values.
*/
observableProto.average = function (keySelector, thisArg) {
var source = this, fn;
if (isFunction(keySelector)) {
fn = bindCallback(keySelector, thisArg, 3);
}
return new AverageObservable(source, fn);
};
/**
* Determines whether two sequences are equal by comparing the elements pairwise using a specified equality comparer.
*
* @example
* var res = res = source.sequenceEqual([1,2,3]);
* var res = res = source.sequenceEqual([{ value: 42 }], function (x, y) { return x.value === y.value; });
* 3 - res = source.sequenceEqual(Rx.Observable.returnValue(42));
* 4 - res = source.sequenceEqual(Rx.Observable.returnValue({ value: 42 }), function (x, y) { return x.value === y.value; });
* @param {Observable} second Second observable sequence or array to compare.
* @param {Function} [comparer] Comparer used to compare elements of both sequences.
* @returns {Observable} An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.
*/
observableProto.sequenceEqual = function (second, comparer) {
var first = this;
comparer || (comparer = defaultComparer);
return new AnonymousObservable(function (o) {
var donel = false, doner = false, ql = [], qr = [];
var subscription1 = first.subscribe(function (x) {
if (qr.length > 0) {
var v = qr.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (doner) {
o.onNext(false);
o.onCompleted();
} else {
ql.push(x);
}
}, function(e) { o.onError(e); }, function () {
donel = true;
if (ql.length === 0) {
if (qr.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (doner) {
o.onNext(true);
o.onCompleted();
}
}
});
(isArrayLike(second) || isIterable(second)) && (second = observableFrom(second));
isPromise(second) && (second = observableFromPromise(second));
var subscription2 = second.subscribe(function (x) {
if (ql.length > 0) {
var v = ql.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (donel) {
o.onNext(false);
o.onCompleted();
} else {
qr.push(x);
}
}, function(e) { o.onError(e); }, function () {
doner = true;
if (qr.length === 0) {
if (ql.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (donel) {
o.onNext(true);
o.onCompleted();
}
}
});
return new BinaryDisposable(subscription1, subscription2);
}, first);
};
var ElementAtObservable = (function (__super__) {
inherits(ElementAtObservable, __super__);
function ElementAtObservable(source, i, d) {
this.source = source;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ElementAtObserver(o, this._i, this._d));
};
return ElementAtObservable;
}(ObservableBase));
var ElementAtObserver = (function (__super__) {
inherits(ElementAtObserver, __super__);
function ElementAtObserver(o, i, d) {
this._o = o;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObserver.prototype.next = function (x) {
if (this._i-- === 0) {
this._o.onNext(x);
this._o.onCompleted();
}
};
ElementAtObserver.prototype.error = function (e) { this._o.onError(e); };
ElementAtObserver.prototype.completed = function () {
if (this._d === undefined) {
this._o.onError(new ArgumentOutOfRangeError());
} else {
this._o.onNext(this._d);
this._o.onCompleted();
}
};
return ElementAtObserver;
}(AbstractObserver));
/**
* Returns the element at a specified index in a sequence or default value if not found.
* @param {Number} index The zero-based index of the element to retrieve.
* @param {Any} [defaultValue] The default value to use if elementAt does not find a value.
* @returns {Observable} An observable sequence that produces the element at the specified position in the source sequence.
*/
observableProto.elementAt = function (index, defaultValue) {
if (index < 0) { throw new ArgumentOutOfRangeError(); }
return new ElementAtObservable(this, index, defaultValue);
};
var SingleObserver = (function(__super__) {
inherits(SingleObserver, __super__);
function SingleObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
SingleObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
if (this._hv) {
return this._o.onError(new Error('Sequence contains more than one matching element'));
}
this._hv = true;
this._v = x;
}
};
SingleObserver.prototype.error = function (e) { this._o.onError(e); };
SingleObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return SingleObserver;
}(AbstractObserver));
/**
* Returns the only element of an observable sequence that satisfies the condition in the optional predicate, and reports an exception if there is not exactly one element in the observable sequence.
* @returns {Observable} Sequence containing the single element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.single = function (predicate, thisArg) {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new AnonymousObservable(function (o) {
return source.subscribe(new SingleObserver(o, obj, source));
}, source);
};
var FirstObservable = (function (__super__) {
inherits(FirstObservable, __super__);
function FirstObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
FirstObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FirstObserver(o, this._obj, this.source));
};
return FirstObservable;
}(ObservableBase));
var FirstObserver = (function(__super__) {
inherits(FirstObserver, __super__);
function FirstObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
__super__.call(this);
}
FirstObserver.prototype.next = function (x) {
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
if (Boolean(res)) {
this._o.onNext(x);
this._o.onCompleted();
}
} else if (!this._obj.predicate) {
this._o.onNext(x);
this._o.onCompleted();
}
};
FirstObserver.prototype.error = function (e) { this._o.onError(e); };
FirstObserver.prototype.completed = function () {
if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return FirstObserver;
}(AbstractObserver));
/**
* Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence.
* @returns {Observable} Sequence containing the first element in the observable sequence that satisfies the condition in the predicate if provided, else the first item in the sequence.
*/
observableProto.first = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new FirstObservable(this, obj);
};
var LastObservable = (function (__super__) {
inherits(LastObservable, __super__);
function LastObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
LastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new LastObserver(o, this._obj, this.source));
};
return LastObservable;
}(ObservableBase));
var LastObserver = (function(__super__) {
inherits(LastObserver, __super__);
function LastObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
LastObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
this._hv = true;
this._v = x;
}
};
LastObserver.prototype.error = function (e) { this._o.onError(e); };
LastObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return LastObserver;
}(AbstractObserver));
/**
* Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element.
* @returns {Observable} Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.last = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new LastObservable(this, obj);
};
var FindValueObserver = (function(__super__) {
inherits(FindValueObserver, __super__);
function FindValueObserver(observer, source, callback, yieldIndex) {
this._o = observer;
this._s = source;
this._cb = callback;
this._y = yieldIndex;
this._i = 0;
__super__.call(this);
}
FindValueObserver.prototype.next = function (x) {
var shouldRun = tryCatch(this._cb)(x, this._i, this._s);
if (shouldRun === errorObj) { return this._o.onError(shouldRun.e); }
if (shouldRun) {
this._o.onNext(this._y ? this._i : x);
this._o.onCompleted();
} else {
this._i++;
}
};
FindValueObserver.prototype.error = function (e) {
this._o.onError(e);
};
FindValueObserver.prototype.completed = function () {
this._y && this._o.onNext(-1);
this._o.onCompleted();
};
return FindValueObserver;
}(AbstractObserver));
function findValue (source, predicate, thisArg, yieldIndex) {
var callback = bindCallback(predicate, thisArg, 3);
return new AnonymousObservable(function (o) {
return source.subscribe(new FindValueObserver(o, source, callback, yieldIndex));
}, source);
}
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the first element that matches the conditions defined by the specified predicate, if found; otherwise, undefined.
*/
observableProto.find = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, false);
};
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns
* an Observable sequence with the zero-based index of the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
*/
observableProto.findIndex = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, true);
};
var ToSetObservable = (function (__super__) {
inherits(ToSetObservable, __super__);
function ToSetObservable(source) {
this.source = source;
__super__.call(this);
}
ToSetObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToSetObserver(o));
};
return ToSetObservable;
}(ObservableBase));
var ToSetObserver = (function (__super__) {
inherits(ToSetObserver, __super__);
function ToSetObserver(o) {
this._o = o;
this._s = new root.Set();
__super__.call(this);
}
ToSetObserver.prototype.next = function (x) {
this._s.add(x);
};
ToSetObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToSetObserver.prototype.completed = function () {
this._o.onNext(this._s);
this._o.onCompleted();
};
return ToSetObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Set if it exists.
* @returns {Observable} An observable sequence with a single value of a Set containing the values from the observable sequence.
*/
observableProto.toSet = function () {
if (typeof root.Set === 'undefined') { throw new TypeError(); }
return new ToSetObservable(this);
};
var ToMapObservable = (function (__super__) {
inherits(ToMapObservable, __super__);
function ToMapObservable(source, k, e) {
this.source = source;
this._k = k;
this._e = e;
__super__.call(this);
}
ToMapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToMapObserver(o, this._k, this._e));
};
return ToMapObservable;
}(ObservableBase));
var ToMapObserver = (function (__super__) {
inherits(ToMapObserver, __super__);
function ToMapObserver(o, k, e) {
this._o = o;
this._k = k;
this._e = e;
this._m = new root.Map();
__super__.call(this);
}
ToMapObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var elem = x;
if (this._e) {
elem = tryCatch(this._e)(x);
if (elem === errorObj) { return this._o.onError(elem.e); }
}
this._m.set(key, elem);
};
ToMapObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToMapObserver.prototype.completed = function () {
this._o.onNext(this._m);
this._o.onCompleted();
};
return ToMapObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Map if it exists.
* @param {Function} keySelector A function which produces the key for the Map.
* @param {Function} [elementSelector] An optional function which produces the element for the Map. If not present, defaults to the value from the observable sequence.
* @returns {Observable} An observable sequence with a single value of a Map containing the values from the observable sequence.
*/
observableProto.toMap = function (keySelector, elementSelector) {
if (typeof root.Map === 'undefined') { throw new TypeError(); }
return new ToMapObservable(this, keySelector, elementSelector);
};
var SliceObservable = (function (__super__) {
inherits(SliceObservable, __super__);
function SliceObservable(source, b, e) {
this.source = source;
this._b = b;
this._e = e;
__super__.call(this);
}
SliceObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SliceObserver(o, this._b, this._e));
};
return SliceObservable;
}(ObservableBase));
var SliceObserver = (function (__super__) {
inherits(SliceObserver, __super__);
function SliceObserver(o, b, e) {
this._o = o;
this._b = b;
this._e = e;
this._i = 0;
__super__.call(this);
}
SliceObserver.prototype.next = function (x) {
if (this._i >= this._b) {
if (this._e === this._i) {
this._o.onCompleted();
} else {
this._o.onNext(x);
}
}
this._i++;
};
SliceObserver.prototype.error = function (e) { this._o.onError(e); };
SliceObserver.prototype.completed = function () { this._o.onCompleted(); };
return SliceObserver;
}(AbstractObserver));
/*
* The slice() method returns a shallow copy of a portion of an Observable into a new Observable object.
* Unlike the array version, this does not support negative numbers for being or end.
* @param {Number} [begin] Zero-based index at which to begin extraction. If omitted, this will default to zero.
* @param {Number} [end] Zero-based index at which to end extraction. slice extracts up to but not including end.
* If omitted, this will emit the rest of the Observable object.
* @returns {Observable} A shallow copy of a portion of an Observable into a new Observable object.
*/
observableProto.slice = function (begin, end) {
var start = begin || 0;
if (start < 0) { throw new Rx.ArgumentOutOfRangeError(); }
if (typeof end === 'number' && end < start) {
throw new Rx.ArgumentOutOfRangeError();
}
return new SliceObservable(this, start, end);
};
var LastIndexOfObservable = (function (__super__) {
inherits(LastIndexOfObservable, __super__);
function LastIndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
LastIndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new LastIndexOfObserver(o, this._e, this._n));
};
return LastIndexOfObservable;
}(ObservableBase));
var LastIndexOfObserver = (function (__super__) {
inherits(LastIndexOfObserver, __super__);
function LastIndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._v = 0;
this._hv = false;
this._i = 0;
__super__.call(this);
}
LastIndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._hv = true;
this._v = this._i;
}
this._i++;
};
LastIndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
LastIndexOfObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
} else {
this._o.onNext(-1);
}
this._o.onCompleted();
};
return LastIndexOfObserver;
}(AbstractObserver));
/**
* Returns the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.lastIndexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new LastIndexOfObservable(this, searchElement, n);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-async/package.json
================================================
{
"name": "rx-lite-async",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with asynchronous functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.async.js"
},
"browser": {
"index.js": "rx.lite.async.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.async.js"
}
================================================
FILE: modules/rx-lite-async/readme.md
================================================
# RxJS Async Module #
The Reactive Extensions for JavaScript provides support for bridging to events, promises, callbacks, Node.js-style callbacks and more. This module includes all of that functionality. In addition, this also supports taking ordinary functions and turning them into asynchronous functions via Observable sequences. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-async
$ npm install -g rx-lite-async
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-async');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`start`](../../doc/api/core/operators/start.md)
- [`startAsync`](../../doc/api/core/operators/startasync.md)
- [`toAsync`](../../doc/api/core/operators/toasync.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-async/rx.lite.async.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableFromPromise = Observable.fromPromise,
observableThrow = Observable.throwError,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AsyncSubject = Rx.AsyncSubject,
disposableCreate = Rx.Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
immediateScheduler = Rx.Scheduler.immediate,
defaultScheduler = Rx.Scheduler['default'],
inherits = Rx.internals.inherits,
isScheduler = Rx.Scheduler.isScheduler,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike;
Observable.wrap = function (fn) {
function createObservable() {
return Observable.spawn.call(this, fn.apply(this, arguments));
}
createObservable.__generatorFunction__ = fn;
return createObservable;
};
var spawn = Observable.spawn = function () {
var gen = arguments[0], self = this, args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return new AnonymousObservable(function (o) {
var g = new CompositeDisposable();
if (isFunction(gen)) { gen = gen.apply(self, args); }
if (!gen || !isFunction(gen.next)) {
o.onNext(gen);
return o.onCompleted();
}
function processGenerator(res) {
var ret = tryCatch(gen.next).call(gen, res);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
processGenerator();
function onError(err) {
var ret = tryCatch(gen.next).call(gen, err);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
function next(ret) {
if (ret.done) {
o.onNext(ret.value);
o.onCompleted();
return;
}
var obs = toObservable.call(self, ret.value);
var value = null;
var hasValue = false;
if (Observable.isObservable(obs)) {
g.add(obs.subscribe(function(val) {
hasValue = true;
value = val;
}, onError, function() {
hasValue && processGenerator(value);
}));
} else {
onError(new TypeError('type not supported'));
}
}
return g;
});
};
function toObservable(obj) {
if (!obj) { return obj; }
if (Observable.isObservable(obj)) { return obj; }
if (isPromise(obj)) { return Observable.fromPromise(obj); }
if (isGeneratorFunction(obj) || isGenerator(obj)) { return spawn.call(this, obj); }
if (isFunction(obj)) { return thunkToObservable.call(this, obj); }
if (isArrayLike(obj) || isIterable(obj)) { return arrayToObservable.call(this, obj); }
if (isObject(obj)) {return objectToObservable.call(this, obj);}
return obj;
}
function arrayToObservable (obj) {
return Observable.from(obj).concatMap(function(o) {
if(Observable.isObservable(o) || isObject(o)) {
return toObservable.call(null, o);
} else {
return Rx.Observable.just(o);
}
}).toArray();
}
function objectToObservable (obj) {
var results = new obj.constructor(), keys = Object.keys(obj), observables = [];
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
var observable = toObservable.call(this, obj[key]);
if(observable && Observable.isObservable(observable)) {
defer(observable, key);
} else {
results[key] = obj[key];
}
}
return Observable.forkJoin.apply(Observable, observables).map(function() {
return results;
});
function defer (observable, key) {
results[key] = undefined;
observables.push(observable.map(function (next) {
results[key] = next;
}));
}
}
function thunkToObservable(fn) {
var self = this;
return new AnonymousObservable(function (o) {
fn.call(self, function () {
var err = arguments[0], res = arguments[1];
if (err) { return o.onError(err); }
if (arguments.length > 2) {
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
res = args;
}
o.onNext(res);
o.onCompleted();
});
});
}
function isGenerator(obj) {
return isFunction (obj.next) && isFunction (obj['throw']);
}
function isGeneratorFunction(obj) {
var ctor = obj.constructor;
if (!ctor) { return false; }
if (ctor.name === 'GeneratorFunction' || ctor.displayName === 'GeneratorFunction') { return true; }
return isGenerator(ctor.prototype);
}
function isObject(val) {
return Object == val.constructor;
}
/**
* Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence.
*
* @example
* var res = Rx.Observable.start(function () { console.log('hello'); });
* var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout);
* var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console);
*
* @param {Function} func Function to run asynchronously.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*
* Remarks
* * The function is called immediately, not during the subscription of the resulting sequence.
* * Multiple subscriptions to the resulting sequence can observe the function's result.
*/
Observable.start = function (func, context, scheduler) {
return observableToAsync(func, context, scheduler)();
};
/**
* Invokes the asynchronous function, surfacing the result through an observable sequence.
* @param {Function} functionAsync Asynchronous function which returns a Promise to run.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*/
Observable.startAsync = function (functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) { return observableThrow(promise.e); }
return observableFromPromise(promise);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-async-compat/package.json
================================================
{
"name": "rx-lite-async-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with asynchronous functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.async.compat.js"
},
"browser": {
"index.js": "rx.lite.async.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.async.compat.js"
}
================================================
FILE: modules/rx-lite-async-compat/readme.md
================================================
# RxJS Async Compat Module #
The Reactive Extensions for JavaScript provides support for bridging to events, promises, callbacks, Node.js-style callbacks and more. This module includes all of that functionality. In addition, this also supports taking ordinary functions and turning them into asynchronous functions via Observable sequences. This requires `rx.lite.compat.js` from the [`rx-lite-compat`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-async-compat
$ npm install -g rx-lite-async-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-async-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`start`](../../doc/api/core/operators/start.md)
- [`startAsync`](../../doc/api/core/operators/startasync.md)
- [`toAsync`](../../doc/api/core/operators/toasync.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-async-compat/rx.lite.async.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableFromPromise = Observable.fromPromise,
observableThrow = Observable.throwError,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AsyncSubject = Rx.AsyncSubject,
disposableCreate = Rx.Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
immediateScheduler = Rx.Scheduler.immediate,
defaultScheduler = Rx.Scheduler['default'],
inherits = Rx.internals.inherits,
isScheduler = Rx.Scheduler.isScheduler,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike;
Observable.wrap = function (fn) {
function createObservable() {
return Observable.spawn.call(this, fn.apply(this, arguments));
}
createObservable.__generatorFunction__ = fn;
return createObservable;
};
var spawn = Observable.spawn = function () {
var gen = arguments[0], self = this, args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return new AnonymousObservable(function (o) {
var g = new CompositeDisposable();
if (isFunction(gen)) { gen = gen.apply(self, args); }
if (!gen || !isFunction(gen.next)) {
o.onNext(gen);
return o.onCompleted();
}
function processGenerator(res) {
var ret = tryCatch(gen.next).call(gen, res);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
processGenerator();
function onError(err) {
var ret = tryCatch(gen.next).call(gen, err);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
function next(ret) {
if (ret.done) {
o.onNext(ret.value);
o.onCompleted();
return;
}
var obs = toObservable.call(self, ret.value);
var value = null;
var hasValue = false;
if (Observable.isObservable(obs)) {
g.add(obs.subscribe(function(val) {
hasValue = true;
value = val;
}, onError, function() {
hasValue && processGenerator(value);
}));
} else {
onError(new TypeError('type not supported'));
}
}
return g;
});
};
function toObservable(obj) {
if (!obj) { return obj; }
if (Observable.isObservable(obj)) { return obj; }
if (isPromise(obj)) { return Observable.fromPromise(obj); }
if (isGeneratorFunction(obj) || isGenerator(obj)) { return spawn.call(this, obj); }
if (isFunction(obj)) { return thunkToObservable.call(this, obj); }
if (isArrayLike(obj) || isIterable(obj)) { return arrayToObservable.call(this, obj); }
if (isObject(obj)) {return objectToObservable.call(this, obj);}
return obj;
}
function arrayToObservable (obj) {
return Observable.from(obj).concatMap(function(o) {
if(Observable.isObservable(o) || isObject(o)) {
return toObservable.call(null, o);
} else {
return Rx.Observable.just(o);
}
}).toArray();
}
function objectToObservable (obj) {
var results = new obj.constructor(), keys = Object.keys(obj), observables = [];
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
var observable = toObservable.call(this, obj[key]);
if(observable && Observable.isObservable(observable)) {
defer(observable, key);
} else {
results[key] = obj[key];
}
}
return Observable.forkJoin.apply(Observable, observables).map(function() {
return results;
});
function defer (observable, key) {
results[key] = undefined;
observables.push(observable.map(function (next) {
results[key] = next;
}));
}
}
function thunkToObservable(fn) {
var self = this;
return new AnonymousObservable(function (o) {
fn.call(self, function () {
var err = arguments[0], res = arguments[1];
if (err) { return o.onError(err); }
if (arguments.length > 2) {
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
res = args;
}
o.onNext(res);
o.onCompleted();
});
});
}
function isGenerator(obj) {
return isFunction (obj.next) && isFunction (obj['throw']);
}
function isGeneratorFunction(obj) {
var ctor = obj.constructor;
if (!ctor) { return false; }
if (ctor.name === 'GeneratorFunction' || ctor.displayName === 'GeneratorFunction') { return true; }
return isGenerator(ctor.prototype);
}
function isObject(val) {
return Object == val.constructor;
}
/**
* Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence.
*
* @example
* var res = Rx.Observable.start(function () { console.log('hello'); });
* var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout);
* var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console);
*
* @param {Function} func Function to run asynchronously.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*
* Remarks
* * The function is called immediately, not during the subscription of the resulting sequence.
* * Multiple subscriptions to the resulting sequence can observe the function's result.
*/
Observable.start = function (func, context, scheduler) {
return observableToAsync(func, context, scheduler)();
};
/**
* Invokes the asynchronous function, surfacing the result through an observable sequence.
* @param {Function} functionAsync Asynchronous function which returns a Promise to run.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*/
Observable.startAsync = function (functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) { return observableThrow(promise.e); }
return observableFromPromise(promise);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-backpressure/package.json
================================================
{
"name": "rx-lite-backpressure",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with backpressure functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.backpressure.js"
},
"browser": {
"index.js": "rx.lite.backpressure.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.backpressure.js"
}
================================================
FILE: modules/rx-lite-backpressure/readme.md
================================================
# RxJS Backpressure Module #
The Reactive Extensions for JavaScript provides support backpressure for situations when the observable sequences emits too many messages for the observer to consume. This is in addition to other mechanisms already in place such as `buffer`, `throttle`, `sample` among other operators which allow you to get messages every so often, or in batches. This module allows you to pause and resume a hot observable with `pausable` and to pause and resume with buffered data with `pausableBuffered`. In addition, we also support the ability to get a requested number of items from the queue through the `controlled` operator.
This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-backpressure
$ npm install -g rx-lite-backpressure
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-backpressure');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Instance Methods`
- [`controlled`](../../doc/api/core/operators/controlled.md)
- [`pausable`](../../doc/api/core/operators/pausable.md)
- [`pausableBuffered`](../../doc/api/core/operators/pausablebuffered.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-backpressure/rx.lite.backpressure.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
NAryDisposable = Rx.NAryDisposable,
Notification = Rx.Notification,
Subject = Rx.Subject,
Observer = Rx.Observer,
disposableEmpty = Rx.Disposable.empty,
disposableCreate = Rx.Disposable.create,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
defaultScheduler = Rx.Scheduler['default'],
currentThreadScheduler = Rx.Scheduler.currentThread,
identity = Rx.helpers.identity,
isScheduler = Rx.Scheduler.isScheduler,
isFunction = Rx.helpers.isFunction,
checkDisposed = Rx.Disposable.checkDisposed;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var StopAndWaitObservable = (function (__super__) {
inherits(StopAndWaitObservable, __super__);
function StopAndWaitObservable (source) {
__super__.call(this);
this.source = source;
}
function scheduleMethod(s, self) {
return self.source.request(1);
}
StopAndWaitObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new StopAndWaitObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var StopAndWaitObserver = (function (__sub__) {
inherits(StopAndWaitObserver, __sub__);
function StopAndWaitObserver (observer, observable, cancel) {
__sub__.call(this);
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.scheduleDisposable = null;
}
StopAndWaitObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
StopAndWaitObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(1);
}
StopAndWaitObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod);
};
StopAndWaitObserver.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return StopAndWaitObserver;
}(AbstractObserver));
return StopAndWaitObservable;
}(Observable));
/**
* Attaches a stop and wait observable to the current observable.
* @returns {Observable} A stop and wait observable.
*/
ControlledObservable.prototype.stopAndWait = function () {
return new StopAndWaitObservable(this);
};
var WindowedObservable = (function (__super__) {
inherits(WindowedObservable, __super__);
function WindowedObservable(source, windowSize) {
__super__.call(this);
this.source = source;
this.windowSize = windowSize;
}
function scheduleMethod(s, self) {
return self.source.request(self.windowSize);
}
WindowedObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new WindowedObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var WindowedObserver = (function (__sub__) {
inherits(WindowedObserver, __sub__);
function WindowedObserver(observer, observable, cancel) {
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.received = 0;
this.scheduleDisposable = null;
__sub__.call(this);
}
WindowedObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
WindowedObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(self.observable.windowSize);
}
WindowedObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.received = ++this.received % this.observable.windowSize;
this.received === 0 && (this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod));
};
WindowedObserver.prototype.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return WindowedObserver;
}(AbstractObserver));
return WindowedObservable;
}(Observable));
/**
* Creates a sliding windowed observable based upon the window size.
* @param {Number} windowSize The number of items in the window
* @returns {Observable} A windowed observable based upon the window size.
*/
ControlledObservable.prototype.windowed = function (windowSize) {
return new WindowedObservable(this, windowSize);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
return Rx;
}));
================================================
FILE: modules/rx-lite-backpressure-compat/package.json
================================================
{
"name": "rx-lite-backpressure-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with backpressure functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.backpressure.compat.js"
},
"browser": {
"index.js": "rx.lite.backpressure.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.backpressure.compat.js"
}
================================================
FILE: modules/rx-lite-backpressure-compat/readme.md
================================================
# RxJS Backpressure Module #
The Reactive Extensions for JavaScript provides support backpressure for situations when the observable sequences emits too many messages for the observer to consume. This is in addition to other mechanisms already in place such as `buffer`, `throttle`, `sample` among other operators which allow you to get messages every so often, or in batches. This module allows you to pause and resume a hot observable with `pausable` and to pause and resume with buffered data with `pausableBuffered`. In addition, we also support the ability to get a requested number of items from the queue through the `controlled` operator.
This requires `rx.lite.compat.js` from the [`rx-lite-compat`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-backpressure-compat
$ npm install -g rx-lite-backpressure-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-backpressure-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Instance Methods`
- [`controlled`](../../doc/api/core/operators/controlled.md)
- [`pausable`](../../doc/api/core/operators/pausable.md)
- [`pausableBuffered`](../../doc/api/core/operators/pausablebuffered.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-backpressure-compat/rx.lite.backpressure.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
NAryDisposable = Rx.NAryDisposable,
Notification = Rx.Notification,
Subject = Rx.Subject,
Observer = Rx.Observer,
disposableEmpty = Rx.Disposable.empty,
disposableCreate = Rx.Disposable.create,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
defaultScheduler = Rx.Scheduler['default'],
currentThreadScheduler = Rx.Scheduler.currentThread,
identity = Rx.helpers.identity,
isScheduler = Rx.Scheduler.isScheduler,
isFunction = Rx.helpers.isFunction,
checkDisposed = Rx.Disposable.checkDisposed;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var StopAndWaitObservable = (function (__super__) {
inherits(StopAndWaitObservable, __super__);
function StopAndWaitObservable (source) {
__super__.call(this);
this.source = source;
}
function scheduleMethod(s, self) {
return self.source.request(1);
}
StopAndWaitObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new StopAndWaitObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var StopAndWaitObserver = (function (__sub__) {
inherits(StopAndWaitObserver, __sub__);
function StopAndWaitObserver (observer, observable, cancel) {
__sub__.call(this);
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.scheduleDisposable = null;
}
StopAndWaitObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
StopAndWaitObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(1);
}
StopAndWaitObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod);
};
StopAndWaitObserver.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return StopAndWaitObserver;
}(AbstractObserver));
return StopAndWaitObservable;
}(Observable));
/**
* Attaches a stop and wait observable to the current observable.
* @returns {Observable} A stop and wait observable.
*/
ControlledObservable.prototype.stopAndWait = function () {
return new StopAndWaitObservable(this);
};
var WindowedObservable = (function (__super__) {
inherits(WindowedObservable, __super__);
function WindowedObservable(source, windowSize) {
__super__.call(this);
this.source = source;
this.windowSize = windowSize;
}
function scheduleMethod(s, self) {
return self.source.request(self.windowSize);
}
WindowedObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new WindowedObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var WindowedObserver = (function (__sub__) {
inherits(WindowedObserver, __sub__);
function WindowedObserver(observer, observable, cancel) {
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.received = 0;
this.scheduleDisposable = null;
__sub__.call(this);
}
WindowedObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
WindowedObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(self.observable.windowSize);
}
WindowedObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.received = ++this.received % this.observable.windowSize;
this.received === 0 && (this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod));
};
WindowedObserver.prototype.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return WindowedObserver;
}(AbstractObserver));
return WindowedObservable;
}(Observable));
/**
* Creates a sliding windowed observable based upon the window size.
* @param {Number} windowSize The number of items in the window
* @returns {Observable} A windowed observable based upon the window size.
*/
ControlledObservable.prototype.windowed = function (windowSize) {
return new WindowedObservable(this, windowSize);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
return Rx;
}));
================================================
FILE: modules/rx-lite-coincidence/package.json
================================================
{
"name": "rx-lite-coincidence",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with coincidence functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.coincidence.js"
},
"browser": {
"index.js": "rx.lite.coincidence.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.coincidence.js"
}
================================================
FILE: modules/rx-lite-coincidence/readme.md
================================================
# RxJS Coincidence Module #
The Reactive Extensions for JavaScript has a set of coincidence-based operators such as `join` and `groupJoin` which allow one to correlate two observable sequences much as you would do in SQL. There is also support for advanced windowing and bufferring capabilities which allow for the specification of opening and closing observable sequences to denote how much data to capture. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-coincidence
$ npm install -g rx-lite-coincidence
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-coincidence');
```
### In a Browser:
```html
```
## Included Observable Operators ##
## `Observable Instance Methods`
- [`buffer`](../../doc/api/core/operators/buffer.md)
- [`groupBy`](../../doc/api/core/operators/groupby.md)
- [`groupByUntil`](../../doc/api/core/operators/groupbyuntil.md)
- [`groupJoin`](../../doc/api/core/operators/groupjoin.md)
- [`join`](../../doc/api/core/operators/join.md)
- [`pairwise`](../../doc/api/core/operators/pairwise.md)
- [`partition`](../../doc/api/core/operators/partition.md)
- [`window`](../../doc/api/core/operators/window.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-coincidence/rx.lite.coincidence.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
var Observable = Rx.Observable,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
Subject = Rx.Subject,
observableProto = Observable.prototype,
observableEmpty = Observable.empty,
observableNever = Observable.never,
AnonymousObservable = Rx.AnonymousObservable,
addRef = Rx.internals.addRef,
inherits = Rx.internals.inherits,
bindCallback = Rx.internals.bindCallback,
noop = Rx.helpers.noop,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* Correlates the elements of two sequences based on overlapping durations.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences. The parameters passed to the function correspond with the elements from the left and right source sequences for which overlap occurs.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.join = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var leftDone = false, rightDone = false;
var leftId = 0, rightId = 0;
var leftMap = new Map(), rightMap = new Map();
var handleError = function (e) { o.onError(e); };
group.add(left.subscribe(
function (value) {
var id = leftId++, md = new SingleAssignmentDisposable();
leftMap.set(id, value);
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
leftMap['delete'](id) && leftMap.size === 0 && leftDone && o.onCompleted();
group.remove(md);
}));
rightMap.forEach(function (v) {
var result = tryCatch(resultSelector)(value, v);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
leftDone = true;
(rightDone || leftMap.size === 0) && o.onCompleted();
})
);
group.add(right.subscribe(
function (value) {
var id = rightId++, md = new SingleAssignmentDisposable();
rightMap.set(id, value);
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
rightMap['delete'](id) && rightMap.size === 0 && rightDone && o.onCompleted();
group.remove(md);
}));
leftMap.forEach(function (v) {
var result = tryCatch(resultSelector)(v, value);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
rightDone = true;
(leftDone || rightMap.size === 0) && o.onCompleted();
})
);
return group;
}, left);
};
/**
* Correlates the elements of two sequences based on overlapping durations, and groups the results.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence. The first parameter passed to the function is an element of the left sequence. The second parameter passed to the function is an observable sequence with elements from the right sequence that overlap with the left sequence's element.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.groupJoin = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var r = new RefCountDisposable(group);
var leftMap = new Map(), rightMap = new Map();
var leftId = 0, rightId = 0;
var handleError = function (e) { return function (v) { v.onError(e); }; };
function handleError(e) { };
group.add(left.subscribe(
function (value) {
var s = new Subject();
var id = leftId++;
leftMap.set(id, s);
var result = tryCatch(resultSelector)(value, addRef(s, r));
if (result === errorObj) {
leftMap.forEach(handleError(result.e));
return o.onError(result.e);
}
o.onNext(result);
rightMap.forEach(function (v) { s.onNext(v); });
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () {
leftMap['delete'](id) && s.onCompleted();
group.remove(md);
}));
},
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () { o.onCompleted(); })
);
group.add(right.subscribe(
function (value) {
var id = rightId++;
rightMap.set(id, value);
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () {
rightMap['delete'](id);
group.remove(md);
}));
leftMap.forEach(function (v) { v.onNext(value); });
},
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
})
);
return r;
}, left);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers.
* @param {Mixed} bufferOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [bufferClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.buffer = function () {
return this.window.apply(this, arguments)
.flatMap(toArray);
};
/**
* Projects each element of an observable sequence into zero or more windows.
*
* @param {Mixed} windowOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [windowClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.window = function (windowOpeningsOrClosingSelector, windowClosingSelector) {
if (arguments.length === 1 && typeof arguments[0] !== 'function') {
return observableWindowWithBoundaries.call(this, windowOpeningsOrClosingSelector);
}
return typeof windowOpeningsOrClosingSelector === 'function' ?
observableWindowWithClosingSelector.call(this, windowOpeningsOrClosingSelector) :
observableWindowWithOpenings.call(this, windowOpeningsOrClosingSelector, windowClosingSelector);
};
function observableWindowWithOpenings(windowOpenings, windowClosingSelector) {
return windowOpenings.groupJoin(this, windowClosingSelector, observableEmpty, function (_, win) {
return win;
});
}
function observableWindowWithBoundaries(windowBoundaries) {
var source = this;
return new AnonymousObservable(function (observer) {
var win = new Subject(),
d = new CompositeDisposable(),
r = new RefCountDisposable(d);
observer.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
isPromise(windowBoundaries) && (windowBoundaries = observableFromPromise(windowBoundaries));
d.add(windowBoundaries.subscribe(function (w) {
win.onCompleted();
win = new Subject();
observer.onNext(addRef(win, r));
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
return r;
}, source);
}
function observableWindowWithClosingSelector(windowClosingSelector) {
var source = this;
return new AnonymousObservable(function (observer) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
r = new RefCountDisposable(d),
win = new Subject();
observer.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
function createWindowClose () {
var windowClose;
try {
windowClose = windowClosingSelector();
} catch (e) {
observer.onError(e);
return;
}
isPromise(windowClose) && (windowClose = observableFromPromise(windowClose));
var m1 = new SingleAssignmentDisposable();
m.setDisposable(m1);
m1.setDisposable(windowClose.take(1).subscribe(noop, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
win = new Subject();
observer.onNext(addRef(win, r));
createWindowClose();
}));
}
createWindowClose();
return r;
}, source);
}
var PairwiseObservable = (function (__super__) {
inherits(PairwiseObservable, __super__);
function PairwiseObservable(source) {
this.source = source;
__super__.call(this);
}
PairwiseObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new PairwiseObserver(o));
};
return PairwiseObservable;
}(ObservableBase));
var PairwiseObserver = (function(__super__) {
inherits(PairwiseObserver, __super__);
function PairwiseObserver(o) {
this._o = o;
this._p = null;
this._hp = false;
__super__.call(this);
}
PairwiseObserver.prototype.next = function (x) {
if (this._hp) {
this._o.onNext([this._p, x]);
} else {
this._hp = true;
}
this._p = x;
};
PairwiseObserver.prototype.error = function (err) { this._o.onError(err); };
PairwiseObserver.prototype.completed = function () { this._o.onCompleted(); };
return PairwiseObserver;
}(AbstractObserver));
/**
* Returns a new observable that triggers on the second and subsequent triggerings of the input observable.
* The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair.
* The argument passed to the N-1th triggering is held in hidden internal state until the Nth triggering occurs.
* @returns {Observable} An observable that triggers on successive pairs of observations from the input observable as an array.
*/
observableProto.pairwise = function () {
return new PairwiseObservable(this);
};
/**
* Returns two observables which partition the observations of the source by the given function.
* The first will trigger observations for those values for which the predicate returns true.
* The second will trigger observations for those values where the predicate returns false.
* The predicate is executed once for each subscribed observer.
* Both also propagate all error observations arising from the source and each completes
* when the source completes.
* @param {Function} predicate
* The function to determine which output Observable will trigger a particular observation.
* @returns {Array}
* An array of observables. The first triggers when the predicate returns true,
* and the second triggers when the predicate returns false.
*/
observableProto.partition = function(predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return [
this.filter(predicate, thisArg),
this.filter(function (x, i, o) { return !fn(x, i, o); })
];
};
/**
* Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
*
* @example
* var res = observable.groupBy(function (x) { return x.id; });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} [elementSelector] A function to map each source element to an element in an observable group.
* @returns {Observable} A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
*/
observableProto.groupBy = function (keySelector, elementSelector) {
return this.groupByUntil(keySelector, elementSelector, observableNever);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function.
* A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
* key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
*
* @example
* var res = observable.groupByUntil(function (x) { return x.id; }, null, function () { return Rx.Observable.never(); });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} durationSelector A function to signal the expiration of a group.
* @returns {Observable}
* A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
* If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
*
*/
observableProto.groupByUntil = function (keySelector, elementSelector, durationSelector) {
var source = this;
return new AnonymousObservable(function (o) {
var map = new Map(),
groupDisposable = new CompositeDisposable(),
refCountDisposable = new RefCountDisposable(groupDisposable),
handleError = function (e) { return function (item) { item.onError(e); }; };
groupDisposable.add(
source.subscribe(function (x) {
var key = tryCatch(keySelector)(x);
if (key === errorObj) {
map.forEach(handleError(key.e));
return o.onError(key.e);
}
var fireNewMapEntry = false, writer = map.get(key);
if (writer === undefined) {
writer = new Subject();
map.set(key, writer);
fireNewMapEntry = true;
}
if (fireNewMapEntry) {
var group = new GroupedObservable(key, writer, refCountDisposable),
durationGroup = new GroupedObservable(key, writer);
var duration = tryCatch(durationSelector)(durationGroup);
if (duration === errorObj) {
map.forEach(handleError(duration.e));
return o.onError(duration.e);
}
o.onNext(group);
var md = new SingleAssignmentDisposable();
groupDisposable.add(md);
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
map.forEach(handleError(e));
o.onError(e);
},
function () {
if (map['delete'](key)) { writer.onCompleted(); }
groupDisposable.remove(md);
}));
}
var element = x;
if (isFunction(elementSelector)) {
element = tryCatch(elementSelector)(x);
if (element === errorObj) {
map.forEach(handleError(element.e));
return o.onError(element.e);
}
}
writer.onNext(element);
}, function (e) {
map.forEach(handleError(e));
o.onError(e);
}, function () {
map.forEach(function (item) { item.onCompleted(); });
o.onCompleted();
}));
return refCountDisposable;
}, source);
};
var UnderlyingObservable = (function (__super__) {
inherits(UnderlyingObservable, __super__);
function UnderlyingObservable(m, u) {
this._m = m;
this._u = u;
__super__.call(this);
}
UnderlyingObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._m.getDisposable(), this._u.subscribe(o));
};
return UnderlyingObservable;
}(ObservableBase));
var GroupedObservable = (function (__super__) {
inherits(GroupedObservable, __super__);
function GroupedObservable(key, underlyingObservable, mergedDisposable) {
__super__.call(this);
this.key = key;
this.underlyingObservable = !mergedDisposable ?
underlyingObservable :
new UnderlyingObservable(mergedDisposable, underlyingObservable);
}
GroupedObservable.prototype._subscribe = function (o) {
return this.underlyingObservable.subscribe(o);
};
return GroupedObservable;
}(Observable));
return Rx;
}));
================================================
FILE: modules/rx-lite-coincidence-compat/package.json
================================================
{
"name": "rx-lite-coincidence-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with coincidence functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.coincidence.compat.js"
},
"browser": {
"index.js": "rx.lite.coincidence.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.coincidence.compat.js"
}
================================================
FILE: modules/rx-lite-coincidence-compat/readme.md
================================================
# RxJS Coincidence Compat Module #
The Reactive Extensions for JavaScript has a set of coincidence-based operators such as `join` and `groupJoin` which allow one to correlate two observable sequences much as you would do in SQL. There is also support for advanced windowing and bufferring capabilities which allow for the specification of opening and closing observable sequences to denote how much data to capture. This requires `rx.lite.compat.js` from the [`rx-lite-compat`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-coincidence-compat
$ npm install -g rx-lite-coincidence-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-coincidence-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
## `Observable Instance Methods`
- [`buffer`](../../doc/api/core/operators/buffer.md)
- [`groupBy`](../../doc/api/core/operators/groupby.md)
- [`groupByUntil`](../../doc/api/core/operators/groupbyuntil.md)
- [`groupJoin`](../../doc/api/core/operators/groupjoin.md)
- [`join`](../../doc/api/core/operators/join.md)
- [`pairwise`](../../doc/api/core/operators/pairwise.md)
- [`partition`](../../doc/api/core/operators/partition.md)
- [`window`](../../doc/api/core/operators/window.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-coincidence-compat/rx.lite.coincidence.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
var Observable = Rx.Observable,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
Subject = Rx.Subject,
observableProto = Observable.prototype,
observableEmpty = Observable.empty,
observableNever = Observable.never,
AnonymousObservable = Rx.AnonymousObservable,
addRef = Rx.internals.addRef,
inherits = Rx.internals.inherits,
bindCallback = Rx.internals.bindCallback,
noop = Rx.helpers.noop,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* Correlates the elements of two sequences based on overlapping durations.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences. The parameters passed to the function correspond with the elements from the left and right source sequences for which overlap occurs.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.join = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var leftDone = false, rightDone = false;
var leftId = 0, rightId = 0;
var leftMap = new Map(), rightMap = new Map();
var handleError = function (e) { o.onError(e); };
group.add(left.subscribe(
function (value) {
var id = leftId++, md = new SingleAssignmentDisposable();
leftMap.set(id, value);
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
leftMap['delete'](id) && leftMap.size === 0 && leftDone && o.onCompleted();
group.remove(md);
}));
rightMap.forEach(function (v) {
var result = tryCatch(resultSelector)(value, v);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
leftDone = true;
(rightDone || leftMap.size === 0) && o.onCompleted();
})
);
group.add(right.subscribe(
function (value) {
var id = rightId++, md = new SingleAssignmentDisposable();
rightMap.set(id, value);
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
rightMap['delete'](id) && rightMap.size === 0 && rightDone && o.onCompleted();
group.remove(md);
}));
leftMap.forEach(function (v) {
var result = tryCatch(resultSelector)(v, value);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
rightDone = true;
(leftDone || rightMap.size === 0) && o.onCompleted();
})
);
return group;
}, left);
};
/**
* Correlates the elements of two sequences based on overlapping durations, and groups the results.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence. The first parameter passed to the function is an element of the left sequence. The second parameter passed to the function is an observable sequence with elements from the right sequence that overlap with the left sequence's element.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.groupJoin = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var r = new RefCountDisposable(group);
var leftMap = new Map(), rightMap = new Map();
var leftId = 0, rightId = 0;
var handleError = function (e) { return function (v) { v.onError(e); }; };
function handleError(e) { };
group.add(left.subscribe(
function (value) {
var s = new Subject();
var id = leftId++;
leftMap.set(id, s);
var result = tryCatch(resultSelector)(value, addRef(s, r));
if (result === errorObj) {
leftMap.forEach(handleError(result.e));
return o.onError(result.e);
}
o.onNext(result);
rightMap.forEach(function (v) { s.onNext(v); });
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () {
leftMap['delete'](id) && s.onCompleted();
group.remove(md);
}));
},
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () { o.onCompleted(); })
);
group.add(right.subscribe(
function (value) {
var id = rightId++;
rightMap.set(id, value);
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
},
function () {
rightMap['delete'](id);
group.remove(md);
}));
leftMap.forEach(function (v) { v.onNext(value); });
},
function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
})
);
return r;
}, left);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers.
* @param {Mixed} bufferOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [bufferClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.buffer = function () {
return this.window.apply(this, arguments)
.flatMap(toArray);
};
/**
* Projects each element of an observable sequence into zero or more windows.
*
* @param {Mixed} windowOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [windowClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.window = function (windowOpeningsOrClosingSelector, windowClosingSelector) {
if (arguments.length === 1 && typeof arguments[0] !== 'function') {
return observableWindowWithBoundaries.call(this, windowOpeningsOrClosingSelector);
}
return typeof windowOpeningsOrClosingSelector === 'function' ?
observableWindowWithClosingSelector.call(this, windowOpeningsOrClosingSelector) :
observableWindowWithOpenings.call(this, windowOpeningsOrClosingSelector, windowClosingSelector);
};
function observableWindowWithOpenings(windowOpenings, windowClosingSelector) {
return windowOpenings.groupJoin(this, windowClosingSelector, observableEmpty, function (_, win) {
return win;
});
}
function observableWindowWithBoundaries(windowBoundaries) {
var source = this;
return new AnonymousObservable(function (observer) {
var win = new Subject(),
d = new CompositeDisposable(),
r = new RefCountDisposable(d);
observer.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
isPromise(windowBoundaries) && (windowBoundaries = observableFromPromise(windowBoundaries));
d.add(windowBoundaries.subscribe(function (w) {
win.onCompleted();
win = new Subject();
observer.onNext(addRef(win, r));
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
return r;
}, source);
}
function observableWindowWithClosingSelector(windowClosingSelector) {
var source = this;
return new AnonymousObservable(function (observer) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
r = new RefCountDisposable(d),
win = new Subject();
observer.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
observer.onCompleted();
}));
function createWindowClose () {
var windowClose;
try {
windowClose = windowClosingSelector();
} catch (e) {
observer.onError(e);
return;
}
isPromise(windowClose) && (windowClose = observableFromPromise(windowClose));
var m1 = new SingleAssignmentDisposable();
m.setDisposable(m1);
m1.setDisposable(windowClose.take(1).subscribe(noop, function (err) {
win.onError(err);
observer.onError(err);
}, function () {
win.onCompleted();
win = new Subject();
observer.onNext(addRef(win, r));
createWindowClose();
}));
}
createWindowClose();
return r;
}, source);
}
var PairwiseObservable = (function (__super__) {
inherits(PairwiseObservable, __super__);
function PairwiseObservable(source) {
this.source = source;
__super__.call(this);
}
PairwiseObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new PairwiseObserver(o));
};
return PairwiseObservable;
}(ObservableBase));
var PairwiseObserver = (function(__super__) {
inherits(PairwiseObserver, __super__);
function PairwiseObserver(o) {
this._o = o;
this._p = null;
this._hp = false;
__super__.call(this);
}
PairwiseObserver.prototype.next = function (x) {
if (this._hp) {
this._o.onNext([this._p, x]);
} else {
this._hp = true;
}
this._p = x;
};
PairwiseObserver.prototype.error = function (err) { this._o.onError(err); };
PairwiseObserver.prototype.completed = function () { this._o.onCompleted(); };
return PairwiseObserver;
}(AbstractObserver));
/**
* Returns a new observable that triggers on the second and subsequent triggerings of the input observable.
* The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair.
* The argument passed to the N-1th triggering is held in hidden internal state until the Nth triggering occurs.
* @returns {Observable} An observable that triggers on successive pairs of observations from the input observable as an array.
*/
observableProto.pairwise = function () {
return new PairwiseObservable(this);
};
/**
* Returns two observables which partition the observations of the source by the given function.
* The first will trigger observations for those values for which the predicate returns true.
* The second will trigger observations for those values where the predicate returns false.
* The predicate is executed once for each subscribed observer.
* Both also propagate all error observations arising from the source and each completes
* when the source completes.
* @param {Function} predicate
* The function to determine which output Observable will trigger a particular observation.
* @returns {Array}
* An array of observables. The first triggers when the predicate returns true,
* and the second triggers when the predicate returns false.
*/
observableProto.partition = function(predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return [
this.filter(predicate, thisArg),
this.filter(function (x, i, o) { return !fn(x, i, o); })
];
};
/**
* Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function.
*
* @example
* var res = observable.groupBy(function (x) { return x.id; });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} [elementSelector] A function to map each source element to an element in an observable group.
* @returns {Observable} A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
*/
observableProto.groupBy = function (keySelector, elementSelector) {
return this.groupByUntil(keySelector, elementSelector, observableNever);
};
/**
* Groups the elements of an observable sequence according to a specified key selector function.
* A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same
* key value as a reclaimed group occurs, the group will be reborn with a new lifetime request.
*
* @example
* var res = observable.groupByUntil(function (x) { return x.id; }, null, function () { return Rx.Observable.never(); });
* 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); });
* 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }, function (x) { return x.toString(); });
* @param {Function} keySelector A function to extract the key for each element.
* @param {Function} durationSelector A function to signal the expiration of a group.
* @returns {Observable}
* A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value.
* If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered.
*
*/
observableProto.groupByUntil = function (keySelector, elementSelector, durationSelector) {
var source = this;
return new AnonymousObservable(function (o) {
var map = new Map(),
groupDisposable = new CompositeDisposable(),
refCountDisposable = new RefCountDisposable(groupDisposable),
handleError = function (e) { return function (item) { item.onError(e); }; };
groupDisposable.add(
source.subscribe(function (x) {
var key = tryCatch(keySelector)(x);
if (key === errorObj) {
map.forEach(handleError(key.e));
return o.onError(key.e);
}
var fireNewMapEntry = false, writer = map.get(key);
if (writer === undefined) {
writer = new Subject();
map.set(key, writer);
fireNewMapEntry = true;
}
if (fireNewMapEntry) {
var group = new GroupedObservable(key, writer, refCountDisposable),
durationGroup = new GroupedObservable(key, writer);
var duration = tryCatch(durationSelector)(durationGroup);
if (duration === errorObj) {
map.forEach(handleError(duration.e));
return o.onError(duration.e);
}
o.onNext(group);
var md = new SingleAssignmentDisposable();
groupDisposable.add(md);
md.setDisposable(duration.take(1).subscribe(
noop,
function (e) {
map.forEach(handleError(e));
o.onError(e);
},
function () {
if (map['delete'](key)) { writer.onCompleted(); }
groupDisposable.remove(md);
}));
}
var element = x;
if (isFunction(elementSelector)) {
element = tryCatch(elementSelector)(x);
if (element === errorObj) {
map.forEach(handleError(element.e));
return o.onError(element.e);
}
}
writer.onNext(element);
}, function (e) {
map.forEach(handleError(e));
o.onError(e);
}, function () {
map.forEach(function (item) { item.onCompleted(); });
o.onCompleted();
}));
return refCountDisposable;
}, source);
};
var UnderlyingObservable = (function (__super__) {
inherits(UnderlyingObservable, __super__);
function UnderlyingObservable(m, u) {
this._m = m;
this._u = u;
__super__.call(this);
}
UnderlyingObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._m.getDisposable(), this._u.subscribe(o));
};
return UnderlyingObservable;
}(ObservableBase));
var GroupedObservable = (function (__super__) {
inherits(GroupedObservable, __super__);
function GroupedObservable(key, underlyingObservable, mergedDisposable) {
__super__.call(this);
this.key = key;
this.underlyingObservable = !mergedDisposable ?
underlyingObservable :
new UnderlyingObservable(mergedDisposable, underlyingObservable);
}
GroupedObservable.prototype._subscribe = function (o) {
return this.underlyingObservable.subscribe(o);
};
return GroupedObservable;
}(Observable));
return Rx;
}));
================================================
FILE: modules/rx-lite-compat/package.json
================================================
{
"name": "rx-lite-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Lite",
"description": "Lightweight IE6 compatible library for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.compat.js"
},
"browser": {
"index.js": "rx.lite.compat.js"
},
"dependencies": {},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.compat.js"
}
================================================
FILE: modules/rx-lite-compat/readme.md
================================================
# RxJS Lite Compatible Module #
The Reactive Extensions for JavaScript Lite version is a lightweight version of the Reactive Extensions for JavaScript which covers most of the day to day operators you might use all in a single library. Functionality such as bridging to events, promises, callbacks, Node.js-style callbacks, time-based operations and more are built right in. This comes with `rx.lite.compat.js` which has backwards compatibility to browsers which do not support all required ES5 features.
## Getting Started
There are a number of ways to get started with RxJS. The files are available on [cdnjs](http://cdnjs.com/libraries/rxjs/) and [jsDelivr](http://www.jsdelivr.com/#!rxjs).
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-compat
$ npm install -g rx-lite-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`catch | catchException`](../../doc/api/core/operators/catch.md)
- [`concat`](../../doc/api/core/operators/concat.md)
- [`create | createWithDisposable`](../../doc/api/core/operators/create.md)
- [`defer`](../../doc/api/core/operators/defer.md)
- [`empty`](../../doc/api/core/operators/empty.md)
- [`from`](../../doc/api/core/operators/from.md)
- [`fromArray`](../../doc/api/core/operators/fromarray.md)
- [`fromCallback`](../../doc/api/core/operators/fromcallback.md)
- [`fromEvent`](../../doc/api/core/operators/fromevent.md)
- [`fromEventPattern`](../../doc/api/core/operators/fromeventpattern.md)
- [`fromNodeCallback`](../../doc/api/core/operators/fromnodecallback.md)
- [`fromPromise`](../../doc/api/core/operators/frompromise.md)
- [`interval`](../../doc/api/core/operators/interval.md)
- [`just`](../../doc/api/core/operators/return.md)
- [`merge`](../../doc/api/core/operators/merge.md)
- [`mergeDelayError`](../../doc/api/core/operators/mergedelayerror.md)
- [`never`](../../doc/api/core/operators/never.md)
- [`of`](../../doc/api/core/operators/of.md)
- [`ofWithScheduler`](../../doc/api/core/operators/ofwithscheduler.md)
- [`range`](../../doc/api/core/operators/range.md)
- [`repeat`](../../doc/api/core/operators/repeat.md)
- [`return | returnValue`](../../doc/api/core/operators/return.md)
- [`throw | throwError | throwException`](../../doc/api/core/operators/throw.md)
- [`timer`](../../doc/api/core/operators/timer.md)
- [`zip`](../../doc/api/core/operators/zip.md)
- [`zipArray`](../../doc/api/core/operators/ziparray.md)
### `Observable Instance Methods`
- [`asObservable`](../../doc/api/core/operators/asobservable.md)
- [`catch | catchException`](../../doc/api/core/operators/catchproto.md)
- [`combineLatest`](../../doc/api/core/operators/combinelatest.md)
- [`concat`](../../doc/api/core/operators/concatproto.md)
- [`concatMap`](../../doc/api/core/operators/concatmap.md)
- [`connect`](../../doc/api/core/operators/connect.md)
- [`debounce`](../../doc/api/core/operators/debounce.md)
- [`defaultIfEmpty`](../../doc/api/core/operators/defaultifempty.md)
- [`delay`](../../doc/api/core/operators/delay.md)
- [`dematerialize`](../../doc/api/core/operators/dematerialize.md)
- [`distinctUntilChanged`](../../doc/api/core/operators/distinctuntilchanged.md)
- [`do | doAction`](../../doc/api/core/operators/do.md)
- [`doOnNext`](../../doc/api/core/operators/doonnext.md)
- [`doOnError`](../../doc/api/core/operators/doonerror.md)
- [`doOnCompleted`](../../doc/api/core/operators/dooncompleted.md)
- [`filter`](../../doc/api/core/operators/where.md)
- [`finally | finallyAction`](../../doc/api/core/operators/finally.md)
- [`flatMap`](../../doc/api/core/operators/selectmany.md)
- [`flatMapLatest`](../../doc/api/core/operators/flatmaplatest.md)
- [`ignoreElements`](../../doc/api/core/operators/ignoreelements.md)
- [`map`](../../doc/api/core/operators/select.md)
- [`merge`](../../doc/api/core/operators/mergeproto.md)
- [`mergeObservable | mergeAll`](../../doc/api/core/operators/mergeall.md)
- [`multicast`](../../doc/api/core/operators/multicast.md)
- [`publish`](../../doc/api/core/operators/publish.md)
- [`publishLast`](../../doc/api/core/operators/publishlast.md)
- [`publishValue`](../../doc/api/core/operators/publishvalue.md)
- [`refCount`](../../doc/api/core/operators/refcount.md)
- [`repeat`](../../doc/api/core/operators/repeat.md)
- [`replay`](../../doc/api/core/operators/replay.md)
- [`retry`](../../doc/api/core/operators/retry.md)
- [`retryWhen`](../../doc/api/core/operators/retrywhen.md)
- [`sample`](../../doc/api/core/operators/sample.md)
- [`scan`](../../doc/api/core/operators/scan.md)
- [`select`](../../doc/api/core/operators/select.md)
- [`selectConcat`](../../doc/api/core/operators/concatmap.md)
- [`selectMany`](../../doc/api/core/operators/selectmany.md)
- [`selectSwitch`](../../doc/api/core/operators/flatmaplatest.md)
- [`singleInstance`](../../doc/api/core/operators/singleinstance.md)
- [`skip`](../../doc/api/core/operators/skip.md)
- [`skipLast`](../../doc/api/core/operators/skiplast.md)
- [`skipUntil`](../../doc/api/core/operators/skipuntil.md)
- [`skipWhile`](../../doc/api/core/operators/skipwhile.md)
- [`startWith`](../../doc/api/core/operators/startwith.md)
- [`subscribe | forEach`](../../doc/api/core/operators/subscribe.md)
- [`subscribeOnNext`](../../doc/api/core/operators/subscribeonnext.md)
- [`subscribeOnError`](../../doc/api/core/operators/subscribeonerror.md)
- [`subscribeOnCompleted`](../../doc/api/core/operators/subscribeoncompleted.md)
- [`switch | switchLatest`](../../doc/api/core/operators/switch.md)
- [`take`](../../doc/api/core/operators/take.md)
- [`takeLast`](../../doc/api/core/operators/takelast.md)
- [`takeUntil`](../../doc/api/core/operators/takeuntil.md)
- [`takeWhile`](../../doc/api/core/operators/takewhile.md)
- [`tap`](../../doc/api/core/operators/do.md)
- [`tapOnNext`](../../doc/api/core/operators/doonnext.md)
- [`tapOnError`](../../doc/api/core/operators/doonerror.md)
- [`tapOnCompleted`](../../doc/api/core/operators/dooncompleted.md)
- [`throttle`](../../doc/api/core/operators/throttle.md)
- [`throttle`](../../doc/api/core/operators/throttle.md)
- [`timeout`](../../doc/api/core/operators/timeout.md)
- [`timestamp`](../../doc/api/core/operators/timestamp.md)
- [`toArray`](../../doc/api/core/operators/toarray.md)
- [`transduce`](../../doc/api/core/operators/transduce.md)
- [`where`](../../doc/api/core/operators/where.md)
- [`withLatestFrom`](../../doc/api/core/operators/withlatestfrom.md)
- [`zip`](../../doc/api/core/operators/zipproto.md)
## Included Classes ##
### Core Objects
- [`Rx.Observer`](../../doc/api/core/observer.md)
- [`Rx.Notification`](../../doc/api/core/notification.md)
### Subjects
- [`Rx.AsyncSubject`](../../doc/api/subjects/asyncsubject.md)
- [`Rx.BehaviorSubject`](../../doc/api/subjects/behaviorsubject.md)
- [`Rx.ReplaySubject`](../../doc/api/subjects/replaysubject.md)
- [`Rx.Subject`](../../doc/api/subjects/subject.md)
### Schedulers
- [`Rx.Scheduler`](../../doc/api/schedulers/scheduler.md)
### Disposables
- [`Rx.CompositeDisposable`](../../doc/api/disposables/compositedisposable.md)
- [`Rx.Disposable`](../../doc/api/disposables/disposable.md)
- [`Rx.RefCountDisposable`](../../doc/api/disposables/refcountdisposable.md)
- [`Rx.SerialDisposable`](../../doc/api/disposables/serialdisposable.md)
- [`Rx.SingleAssignmentDisposable`](../../doc/api/disposables/singleassignmentdisposable.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-compat/rx.lite.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
// Utilities
var toString = Object.prototype.toString;
var arrayClass = '[object Array]',
funcClass = '[object Function]',
stringClass = '[object String]';
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k++;
}
};
}
var boxedString = Object('a'),
splitString = boxedString[0] !== 'a' || !(0 in boxedString);
if (!Array.prototype.every) {
Array.prototype.every = function every(fun /*, thisp */) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self && !fun.call(thisp, self[i], i, object)) {
return false;
}
}
return true;
};
}
if (!Array.prototype.map) {
Array.prototype.map = function map(fun /*, thisp*/) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
result = new Array(length),
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self) {
result[i] = fun.call(thisp, self[i], i, object);
}
}
return result;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function (predicate) {
var results = [], item, t = new Object(this);
for (var i = 0, len = t.length >>> 0; i < len; i++) {
item = t[i];
if (i in t && predicate.call(arguments[1], item, i, t)) {
results.push(item);
}
}
return results;
};
}
if (!Array.isArray) {
Array.isArray = function (arg) {
return toString.call(arg) === arrayClass;
};
}
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(searchElement) {
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== Infinity && n !== -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
// Fix for Tessel
if (!Object.prototype.propertyIsEnumerable) {
Object.prototype.propertyIsEnumerable = function (key) {
for (var k in this) { if (k === key) { return true; } }
return false;
};
}
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
if (typeof Object.create !== 'function') {
// Production steps of ECMA-262, Edition 5, 15.2.3.5
// Reference: http://es5.github.io/#x15.2.3.5
Object.create = (function() {
function Temp() {}
var hasOwn = Object.prototype.hasOwnProperty;
return function (O) {
if (typeof O !== 'object') {
throw new TypeError('Object prototype may only be an Object or null');
}
Temp.prototype = O;
var obj = new Temp();
Temp.prototype = null;
if (arguments.length > 1) {
// Object.defineProperties does ToObject on its first argument.
var Properties = Object(arguments[1]);
for (var prop in Properties) {
if (hasOwn.call(Properties, prop)) {
obj[prop] = Properties[prop];
}
}
}
// 5. Return obj
return obj;
};
})();
}
root.Element && root.Element.prototype.attachEvent && !root.Element.prototype.addEventListener && (function () {
function addMethod(name, fn) {
Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = fn;
}
addMethod('addEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
target.attachEvent('on' + type, typeListeners.event = function (e) {
e || (e = root.event);
var documentElement = target.document &&
target.document.documentElement ||
target.documentElement ||
{ scrollLeft: 0, scrollTop: 0 };
e.currentTarget = target;
e.pageX = e.clientX + documentElement.scrollLeft;
e.pageY = e.clientY + documentElement.scrollTop;
e.preventDefault = function () {
e.bubbledKeyCode = e.keyCode;
if (e.ctrlKey) {
try {
e.keyCode = 0;
} catch (e) { }
}
e.defaultPrevented = true;
e.returnValue = false;
e.modified = true;
e.returnValue = false;
};
e.stopImmediatePropagation = function () {
immediatePropagation = false;
e.cancelBubble = true;
};
e.stopPropagation = function () {
e.cancelBubble = true;
};
e.relatedTarget = e.fromElement || null;
e.target = e.srcElement || target;
e.timeStamp = +new Date();
// Normalize key events
switch(e.type) {
case 'keypress':
var c = ('charCode' in e ? e.charCode : e.keyCode);
if (c === 10) {
c = 0;
e.keyCode = 13;
} else if (c === 13 || c === 27) {
c = 0;
} else if (c === 3) {
c = 99;
}
e.charCode = c;
e.keyChar = e.charCode ? String.fromCharCode(e.charCode) : '';
break;
}
var copiedEvent = {};
for (var prop in e) {
copiedEvent[prop] = e[prop];
}
for (var i = 0, typeListenersCache = [].concat(typeListeners), typeListenerCache, immediatePropagation = true; immediatePropagation && (typeListenerCache = typeListenersCache[i]); ++i) {
for (var ii = 0, typeListener; typeListener = typeListeners[ii]; ++ii) {
if (typeListener === typeListenerCache) { typeListener.call(target, copiedEvent); break; }
}
}
});
typeListeners.push(listener);
});
addMethod('removeEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
for (var i = typeListeners.length - 1, typeListener; typeListener = typeListeners[i]; --i) {
if (typeListener === listener) { typeListeners.splice(i, 1); break; }
}
!typeListeners.length &&
typeListeners.event &&
target.detachEvent('on' + type, typeListeners.event);
});
addMethod('dispatchEvent', function (e) {
var target = this;
var type = e.type;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
try {
return target.fireEvent('on' + type, e);
} catch (err) {
return typeListeners.event && typeListeners.event(e);
}
});
function ready() {
if (ready.interval && document.body) {
ready.interval = clearInterval(ready.interval);
document.dispatchEvent(new CustomEvent('DOMContentLoaded'));
}
}
ready.interval = setInterval(ready, 1);
root.addEventListener('load', ready);
}());
(!root.CustomEvent || typeof root.CustomEvent === 'object') && (function() {
function CustomEvent (type, params) {
var event;
params = params || { bubbles: false, cancelable: false, detail: undefined };
try {
if (document.createEvent) {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
} else if (document.createEventObject) {
event = document.createEventObject();
}
} catch (error) {
event = document.createEvent('Event');
event.initEvent(type, params.bubbles, params.cancelable);
event.detail = params.detail;
}
return event;
}
root.CustomEvent && (CustomEvent.prototype = root.CustomEvent.prototype);
root.CustomEvent = CustomEvent;
}());
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
var ScheduledObserver = Rx.internals.ScheduledObserver = (function (__super__) {
inherits(ScheduledObserver, __super__);
function ScheduledObserver(scheduler, observer) {
__super__.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
function enqueueNext(observer, x) { return function () { observer.onNext(x); }; }
function enqueueError(observer, e) { return function () { observer.onError(e); }; }
function enqueueCompleted(observer) { return function () { observer.onCompleted(); }; }
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.disposable.dispose();
};
return ScheduledObserver;
}(AbstractObserver));
var ToArrayObservable = (function(__super__) {
inherits(ToArrayObservable, __super__);
function ToArrayObservable(source) {
this.source = source;
__super__.call(this);
}
ToArrayObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o) {
this.o = o;
this.a = [];
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) { this.a.push(x); };
InnerObserver.prototype.error = function (e) { this.o.onError(e); };
InnerObserver.prototype.completed = function () { this.o.onNext(this.a); this.o.onCompleted(); };
return ToArrayObservable;
}(ObservableBase));
/**
* Creates an array from an observable sequence.
* @returns {Observable} An observable sequence containing a single element with a list containing all the elements of the source sequence.
*/
observableProto.toArray = function () {
return new ToArrayObservable(this);
};
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
var MergeAllObservable = (function (__super__) {
inherits(MergeAllObservable, __super__);
function MergeAllObservable(source) {
this.source = source;
__super__.call(this);
}
MergeAllObservable.prototype.subscribeCore = function (o) {
var g = new CompositeDisposable(), m = new SingleAssignmentDisposable();
g.add(m);
m.setDisposable(this.source.subscribe(new MergeAllObserver(o, g)));
return g;
};
return MergeAllObservable;
}(ObservableBase));
var MergeAllObserver = (function (__super__) {
function MergeAllObserver(o, g) {
this.o = o;
this.g = g;
this.done = false;
__super__.call(this);
}
inherits(MergeAllObserver, __super__);
MergeAllObserver.prototype.next = function(innerSource) {
var sad = new SingleAssignmentDisposable();
this.g.add(sad);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
sad.setDisposable(innerSource.subscribe(new InnerObserver(this, sad)));
};
MergeAllObserver.prototype.error = function (e) {
this.o.onError(e);
};
MergeAllObserver.prototype.completed = function () {
this.done = true;
this.g.length === 1 && this.o.onCompleted();
};
function InnerObserver(parent, sad) {
this.parent = parent;
this.sad = sad;
__super__.call(this);
}
inherits(InnerObserver, __super__);
InnerObserver.prototype.next = function (x) {
this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.parent.g.remove(this.sad);
this.parent.done && this.parent.g.length === 1 && this.parent.o.onCompleted();
};
return MergeAllObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.mergeAll = function () {
return new MergeAllObservable(this);
};
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
var TakeUntilObservable = (function(__super__) {
inherits(TakeUntilObservable, __super__);
function TakeUntilObservable(source, other) {
this.source = source;
this.other = isPromise(other) ? observableFromPromise(other) : other;
__super__.call(this);
}
TakeUntilObservable.prototype.subscribeCore = function(o) {
return new BinaryDisposable(
this.source.subscribe(o),
this.other.subscribe(new TakeUntilObserver(o))
);
};
return TakeUntilObservable;
}(ObservableBase));
var TakeUntilObserver = (function(__super__) {
inherits(TakeUntilObserver, __super__);
function TakeUntilObserver(o) {
this._o = o;
__super__.call(this);
}
TakeUntilObserver.prototype.next = function () {
this._o.onCompleted();
};
TakeUntilObserver.prototype.error = function (err) {
this._o.onError(err);
};
TakeUntilObserver.prototype.onCompleted = noop;
return TakeUntilObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence until the other observable sequence produces a value.
* @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation.
*/
observableProto.takeUntil = function (other) {
return new TakeUntilObservable(this, other);
};
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var WithLatestFromObservable = (function(__super__) {
inherits(WithLatestFromObservable, __super__);
function WithLatestFromObservable(source, sources, resultSelector) {
this._s = source;
this._ss = sources;
this._cb = resultSelector;
__super__.call(this);
}
WithLatestFromObservable.prototype.subscribeCore = function (o) {
var len = this._ss.length;
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
values: new Array(len)
};
var n = this._ss.length, subscriptions = new Array(n + 1);
for (var i = 0; i < n; i++) {
var other = this._ss[i], sad = new SingleAssignmentDisposable();
isPromise(other) && (other = observableFromPromise(other));
sad.setDisposable(other.subscribe(new WithLatestFromOtherObserver(o, i, state)));
subscriptions[i] = sad;
}
var outerSad = new SingleAssignmentDisposable();
outerSad.setDisposable(this._s.subscribe(new WithLatestFromSourceObserver(o, this._cb, state)));
subscriptions[n] = outerSad;
return new NAryDisposable(subscriptions);
};
return WithLatestFromObservable;
}(ObservableBase));
var WithLatestFromOtherObserver = (function (__super__) {
inherits(WithLatestFromOtherObserver, __super__);
function WithLatestFromOtherObserver(o, i, state) {
this._o = o;
this._i = i;
this._state = state;
__super__.call(this);
}
WithLatestFromOtherObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
this._state.hasValueAll = this._state.hasValue.every(identity);
};
WithLatestFromOtherObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromOtherObserver.prototype.completed = noop;
return WithLatestFromOtherObserver;
}(AbstractObserver));
var WithLatestFromSourceObserver = (function (__super__) {
inherits(WithLatestFromSourceObserver, __super__);
function WithLatestFromSourceObserver(o, cb, state) {
this._o = o;
this._cb = cb;
this._state = state;
__super__.call(this);
}
WithLatestFromSourceObserver.prototype.next = function (x) {
var allValues = [x].concat(this._state.values);
if (!this._state.hasValueAll) { return; }
var res = tryCatch(this._cb).apply(null, allValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
};
WithLatestFromSourceObserver.prototype.error = function (e) {
this._o.onError(e);
};
WithLatestFromSourceObserver.prototype.completed = function () {
this._o.onCompleted();
};
return WithLatestFromSourceObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function only when the (first) source observable sequence produces an element.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.withLatestFrom = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new WithLatestFromObservable(this, args, resultSelector);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
var ZipObservable = (function(__super__) {
inherits(ZipObservable, __super__);
function ZipObservable(sources, resultSelector) {
this._s = sources;
this._cb = resultSelector;
__super__.call(this);
}
ZipObservable.prototype.subscribeCore = function(observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = arrayInitialize(n, falseFactory),
q = arrayInitialize(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
return ZipObservable;
}(ObservableBase));
var ZipObserver = (function (__super__) {
inherits(ZipObserver, __super__);
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
return ZipObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zip = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
var parent = this;
args.unshift(parent);
return new ZipObservable(args, resultSelector);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
var TapObservable = (function(__super__) {
inherits(TapObservable,__super__);
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
__super__.call(this);
}
TapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, p) {
this.o = o;
this.t = !p._oN || isFunction(p._oN) ?
observerCreate(p._oN || noop, p._oE || noop, p._oC || noop) :
p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var res = tryCatch(this.t.onNext).call(this.t, x);
if (res === errorObj) { this.o.onError(res.e); }
this.o.onNext(x);
};
InnerObserver.prototype.error = function(err) {
var res = tryCatch(this.t.onError).call(this.t, err);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onError(err);
};
InnerObserver.prototype.completed = function() {
var res = tryCatch(this.t.onCompleted).call(this.t);
if (res === errorObj) { return this.o.onError(res.e); }
this.o.onCompleted();
};
return TapObservable;
}(ObservableBase));
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto['do'] = observableProto.tap = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) {
return new TapObservable(this, observerOrOnNext, onError, onCompleted);
};
/**
* Invokes an action for each element in the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onNext Action to invoke for each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnNext = observableProto.tapOnNext = function (onNext, thisArg) {
return this.tap(typeof thisArg !== 'undefined' ? function (x) { onNext.call(thisArg, x); } : onNext);
};
/**
* Invokes an action upon exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onError Action to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnError = observableProto.tapOnError = function (onError, thisArg) {
return this.tap(noop, typeof thisArg !== 'undefined' ? function (e) { onError.call(thisArg, e); } : onError);
};
/**
* Invokes an action upon graceful termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function} onCompleted Action to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
observableProto.doOnCompleted = observableProto.tapOnCompleted = function (onCompleted, thisArg) {
return this.tap(noop, null, typeof thisArg !== 'undefined' ? function () { onCompleted.call(thisArg); } : onCompleted);
};
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
/**
* Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely.
* @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely.
* @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly.
*/
observableProto.repeat = function (repeatCount) {
return enumerableRepeat(this, repeatCount).concat();
};
/**
* Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely.
* Note if you encounter an error and want it to retry once, then you must use .retry(2);
*
* @example
* var res = retried = retry.repeat();
* var res = retried = retry.repeat(2);
* @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely.
* @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
observableProto.retry = function (retryCount) {
return enumerableRepeat(this, retryCount).catchError();
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RetryWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RetryWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RetryWhenObservable, __super__);
RetryWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RetryWhenObservable;
}(ObservableBase));
observableProto.retryWhen = function (notifier) {
return new RetryWhenObservable(repeat(this), notifier);
};
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
var RepeatWhenObservable = (function(__super__) {
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
__super__.call(this);
}
inherits(RepeatWhenObservable, __super__);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source['@@iterator']();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = currentThreadScheduler.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
return RepeatWhenObservable;
}(ObservableBase));
observableProto.repeatWhen = function (notifier) {
return new RepeatWhenObservable(repeat(this), notifier);
};
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
var MapObservable = (function (__super__) {
inherits(MapObservable, __super__);
function MapObservable(source, selector, thisArg) {
this.source = source;
this.selector = bindCallback(selector, thisArg, 3);
__super__.call(this);
}
function innerMap(selector, self) {
return function (x, i, o) { return selector.call(this, self.selector(x, i, o), i, o); };
}
MapObservable.prototype.internalMap = function (selector, thisArg) {
return new MapObservable(this.source, innerMap(selector, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, selector, source) {
this.o = o;
this.selector = selector;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var result = tryCatch(this.selector)(x, this.i++, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
this.o.onNext(result);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return MapObservable;
}(ObservableBase));
/**
* Projects each element of an observable sequence into a new form by incorporating the element's index.
* @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
observableProto.map = observableProto.select = function (selector, thisArg) {
var selectorFn = typeof selector === 'function' ? selector : function () { return selector; };
return this instanceof MapObservable ?
this.internalMap(selectorFn, thisArg) :
new MapObservable(this, selectorFn, thisArg);
};
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
observableProto.pluck = function () {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return this.map(plucker(args, len));
};
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
var SampleObservable = (function(__super__) {
inherits(SampleObservable, __super__);
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
__super__.call(this);
}
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
return SampleObservable;
}(ObservableBase));
var SamplerObserver = (function(__super__) {
inherits(SamplerObserver, __super__);
function SamplerObserver(s) {
this._s = s;
__super__.call(this);
}
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
return SamplerObserver;
}(AbstractObserver));
var SampleSourceObserver = (function(__super__) {
inherits(SampleSourceObserver, __super__);
function SampleSourceObserver(s) {
this._s = s;
__super__.call(this);
}
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
return SampleSourceObserver;
}(AbstractObserver));
/**
* Samples the observable sequence at each interval.
*
* @example
* 1 - res = source.sample(sampleObservable); // Sampler tick sequence
* 2 - res = source.sample(5000); // 5 seconds
* 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds
*
* @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable.
* @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Sampled observable sequence.
*/
observableProto.sample = function (intervalOrSampler, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(this, observableinterval(intervalOrSampler, scheduler)) :
new SampleObservable(this, intervalOrSampler);
};
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
var PausableObservable = (function (__super__) {
inherits(PausableObservable, __super__);
function PausableObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableObservable.prototype._subscribe = function (o) {
var conn = this.source.publish(),
subscription = conn.subscribe(o),
connection = disposableEmpty;
var pausable = this.pauser.startWith(!this.paused).distinctUntilChanged().subscribe(function (b) {
if (b) {
connection = conn.connect();
} else {
connection.dispose();
connection = disposableEmpty;
}
});
return new NAryDisposable([subscription, connection, pausable]);
};
PausableObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausable = function (pauser) {
return new PausableObservable(this, pauser);
};
function combineLatestSource(source, subject, resultSelector) {
return new AnonymousObservable(function (o) {
var hasValue = [false, false],
hasValueAll = false,
isDone = false,
values = new Array(2),
err;
function next(x, i) {
values[i] = x;
hasValue[i] = true;
if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
if (err) { return o.onError(err); }
var res = tryCatch(resultSelector).apply(null, values);
if (res === errorObj) { return o.onError(res.e); }
o.onNext(res);
}
isDone && values[1] && o.onCompleted();
}
return new BinaryDisposable(
source.subscribe(
function (x) {
next(x, 0);
},
function (e) {
if (values[1]) {
o.onError(e);
} else {
err = e;
}
},
function () {
isDone = true;
values[1] && o.onCompleted();
}),
subject.subscribe(
function (x) {
next(x, 1);
},
function (e) { o.onError(e); },
function () {
isDone = true;
next(true, 1);
})
);
}, source);
}
var PausableBufferedObservable = (function (__super__) {
inherits(PausableBufferedObservable, __super__);
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableBufferedObservable.prototype._subscribe = function (o) {
var q = [], previousShouldFire;
function drainQueue() { while (q.length > 0) { o.onNext(q.shift()); } }
var subscription =
combineLatestSource(
this.source,
this.pauser.startWith(!this.paused).distinctUntilChanged(),
function (data, shouldFire) {
return { data: data, shouldFire: shouldFire };
})
.subscribe(
function (results) {
if (previousShouldFire !== undefined && results.shouldFire !== previousShouldFire) {
previousShouldFire = results.shouldFire;
// change in shouldFire
if (results.shouldFire) { drainQueue(); }
} else {
previousShouldFire = results.shouldFire;
// new data
if (results.shouldFire) {
o.onNext(results.data);
} else {
q.push(results.data);
}
}
},
function (err) {
drainQueue();
o.onError(err);
},
function () {
drainQueue();
o.onCompleted();
}
);
return subscription;
};
PausableBufferedObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableBufferedObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableBufferedObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausableBuffered = function (pauser) {
return new PausableBufferedObservable(this, pauser);
};
var ControlledObservable = (function (__super__) {
inherits(ControlledObservable, __super__);
function ControlledObservable (source, enableQueue, scheduler) {
__super__.call(this);
this.subject = new ControlledSubject(enableQueue, scheduler);
this.source = source.multicast(this.subject).refCount();
}
ControlledObservable.prototype._subscribe = function (o) {
return this.source.subscribe(o);
};
ControlledObservable.prototype.request = function (numberOfItems) {
return this.subject.request(numberOfItems == null ? -1 : numberOfItems);
};
return ControlledObservable;
}(Observable));
var ControlledSubject = (function (__super__) {
inherits(ControlledSubject, __super__);
function ControlledSubject(enableQueue, scheduler) {
enableQueue == null && (enableQueue = true);
__super__.call(this);
this.subject = new Subject();
this.enableQueue = enableQueue;
this.queue = enableQueue ? [] : null;
this.requestedCount = 0;
this.requestedDisposable = null;
this.error = null;
this.hasFailed = false;
this.hasCompleted = false;
this.scheduler = scheduler || currentThreadScheduler;
}
addProperties(ControlledSubject.prototype, Observer, {
_subscribe: function (o) {
return this.subject.subscribe(o);
},
onCompleted: function () {
this.hasCompleted = true;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onCompleted();
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnCompleted());
}
},
onError: function (error) {
this.hasFailed = true;
this.error = error;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onError(error);
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnError(error));
}
},
onNext: function (value) {
if (this.requestedCount <= 0) {
this.enableQueue && this.queue.push(Notification.createOnNext(value));
} else {
(this.requestedCount-- === 0) && this.disposeCurrentRequest();
this.subject.onNext(value);
}
},
_processRequest: function (numberOfItems) {
if (this.enableQueue) {
while (this.queue.length > 0 && (numberOfItems > 0 || this.queue[0].kind !== 'N')) {
var first = this.queue.shift();
first.accept(this.subject);
if (first.kind === 'N') {
numberOfItems--;
} else {
this.disposeCurrentRequest();
this.queue = [];
}
}
}
return numberOfItems;
},
request: function (number) {
this.disposeCurrentRequest();
var self = this;
this.requestedDisposable = this.scheduler.schedule(number,
function(s, i) {
var remaining = self._processRequest(i);
var stopped = self.hasCompleted || self.hasFailed;
if (!stopped && remaining > 0) {
self.requestedCount = remaining;
return disposableCreate(function () {
self.requestedCount = 0;
});
// Scheduled item is still in progress. Return a new
// disposable to allow the request to be interrupted
// via dispose.
}
});
return this.requestedDisposable;
},
disposeCurrentRequest: function () {
if (this.requestedDisposable) {
this.requestedDisposable.dispose();
this.requestedDisposable = null;
}
}
});
return ControlledSubject;
}(Observable));
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
observableProto.controlled = function (enableQueue, scheduler) {
if (enableQueue && isScheduler(enableQueue)) {
scheduler = enableQueue;
enableQueue = true;
}
if (enableQueue == null) { enableQueue = true; }
return new ControlledObservable(this, enableQueue, scheduler);
};
/**
* Pipes the existing Observable sequence into a Node.js Stream.
* @param {Stream} dest The destination Node.js stream.
* @returns {Stream} The destination stream.
*/
observableProto.pipe = function (dest) {
var source = this.pausableBuffered();
function onDrain() {
source.resume();
}
dest.addListener('drain', onDrain);
source.subscribe(
function (x) {
!dest.write(x) && source.pause();
},
function (err) {
dest.emit('error', err);
},
function () {
// Hack check because STDIO is not closable
!dest._isStdio && dest.end();
dest.removeListener('drain', onDrain);
});
source.resume();
return dest;
};
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
var InnerSubscription = function (s, o) {
this._s = s;
this._o = o;
};
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
var Subject = Rx.Subject = (function (__super__) {
inherits(Subject, __super__);
function Subject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return disposableEmpty;
}
o.onCompleted();
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
/**
* Creates a subject from the specified observer and observable.
* @param {Observer} observer The observer used to send messages to the subject.
* @param {Observable} observable The observable used to subscribe to messages sent from the subject.
* @returns {Subject} Subject implemented using the given observer and observable.
*/
Subject.create = function (observer, observable) {
return new AnonymousSubject(observer, observable);
};
return Subject;
}(Observable));
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
inherits(AsyncSubject, __super__);
/**
* Creates a subject that can only receive one value and that value is cached for all future observations.
* @constructor
*/
function AsyncSubject() {
__super__.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i, len;
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers), len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
return AsyncSubject;
}(Observable));
var AnonymousSubject = Rx.AnonymousSubject = (function (__super__) {
inherits(AnonymousSubject, __super__);
function AnonymousSubject(observer, observable) {
this.observer = observer;
this.observable = observable;
__super__.call(this);
}
addProperties(AnonymousSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
return this.observable.subscribe(o);
},
onCompleted: function () {
this.observer.onCompleted();
},
onError: function (error) {
this.observer.onError(error);
},
onNext: function (value) {
this.observer.onNext(value);
}
});
return AnonymousSubject;
}(Observable));
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
var BehaviorSubject = Rx.BehaviorSubject = (function (__super__) {
inherits(BehaviorSubject, __super__);
function BehaviorSubject(value) {
__super__.call(this);
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
}
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return disposableEmpty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
checkDisposed(this);
if (this.hasError) { thrower(this.error); }
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
return BehaviorSubject;
}(Observable));
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*/
var ReplaySubject = Rx.ReplaySubject = (function (__super__) {
var maxSafeInteger = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return disposableCreate(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
inherits(ReplaySubject, __super__);
/**
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? maxSafeInteger : bufferSize;
this.windowSize = windowSize == null ? maxSafeInteger : windowSize;
this.scheduler = scheduler || currentThreadScheduler;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
__super__.call(this);
}
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o), subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () { checkDisposed(this); return this.observers.length > 0; },
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
checkDisposed(this);
if (this.isStopped) { return; }
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
checkDisposed(this);
if (this.isStopped) { return; }
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
return ReplaySubject;
}(Observable));
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
}.call(this));
================================================
FILE: modules/rx-lite-experimental/package.json
================================================
{
"name": "rx-lite-experimental",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with experimental functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.experimental.js"
},
"browser": {
"index.js": "rx.lite.experimental.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.experimental.js"
}
================================================
FILE: modules/rx-lite-experimental/readme.md
================================================
# RxJS Experimental Module #
The Reactive Extensions for JavaScript has a number of operators that are considered experimental and not ready for mainstream usage. This includes imperative operators such as `if`, `case`, `for`, `while`, `doWhile` as well as operators such as `forkJoin`. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-experimental
$ npm install -g rx-lite-experimental
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-experimental');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`case | switchCase`](../../doc/api/core/operators/case.md)
- [`for | forIn`](../../doc/api/core/operators/for.md)
- [`forkJoin`](../../doc/api/core/operators/forkjoin.md)
- [`if | ifThen`](../../doc/api/core/operators/if.md)
- [`while | whileDo`](../../doc/api/core/operators/while.md)
### `Observable Instance Methods`
- [`doWhile`](/api/core/operators/dowhile.md)
- [`expand`](../../doc/api/core/operators/expand.md)
- [`forkJoin`](../../doc/api/core/operators/forkjoinproto.md)
- [`let | letBind`](../../doc/api/core/operators/let.md)
- [`manySelect`](../../doc/api/core/operators/manyselect.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-experimental/rx.lite.experimental.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
FlatMapObservable = Rx.FlatMapObservable,
observableConcat = Observable.concat,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
disposableEmpty = Rx.Disposable.empty,
CompositeDisposable = Rx.CompositeDisposable,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Enumerable = Rx.internals.Enumerable,
enumerableOf = Enumerable.of,
currentThreadScheduler = Rx.Scheduler.currentThread,
AsyncSubject = Rx.AsyncSubject,
Observer = Rx.Observer,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
helpers = Rx.helpers,
noop = helpers.noop,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var WhileEnumerable = (function(__super__) {
inherits(WhileEnumerable, __super__);
function WhileEnumerable(c, s) {
this.c = c;
this.s = s;
}
WhileEnumerable.prototype[$iterator$] = function () {
var self = this;
return {
next: function () {
return self.c() ?
{ done: false, value: self.s } :
{ done: true, value: void 0 };
}
};
};
return WhileEnumerable;
}(Enumerable));
function enumerableWhile(condition, source) {
return new WhileEnumerable(condition, source);
}
/**
* Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions.
* This operator allows for a fluent style of writing queries that use the same sequence multiple times.
*
* @param {Function} selector Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
observableProto.letBind = observableProto['let'] = function (func) {
return func(this);
};
/**
* Determines whether an observable collection contains values.
*
* @example
* 1 - res = Rx.Observable.if(condition, obs1);
* 2 - res = Rx.Observable.if(condition, obs1, obs2);
* 3 - res = Rx.Observable.if(condition, obs1, scheduler);
* @param {Function} condition The condition which determines if the thenSource or elseSource will be run.
* @param {Observable} thenSource The observable sequence or Promise that will be run if the condition function returns true.
* @param {Observable} [elseSource] The observable sequence or Promise that will be run if the condition function returns false. If this is not provided, it defaults to Rx.Observabe.Empty with the specified scheduler.
* @returns {Observable} An observable sequence which is either the thenSource or elseSource.
*/
Observable['if'] = function (condition, thenSource, elseSourceOrScheduler) {
return observableDefer(function () {
elseSourceOrScheduler || (elseSourceOrScheduler = observableEmpty());
isPromise(thenSource) && (thenSource = observableFromPromise(thenSource));
isPromise(elseSourceOrScheduler) && (elseSourceOrScheduler = observableFromPromise(elseSourceOrScheduler));
// Assume a scheduler for empty only
typeof elseSourceOrScheduler.now === 'function' && (elseSourceOrScheduler = observableEmpty(elseSourceOrScheduler));
return condition() ? thenSource : elseSourceOrScheduler;
});
};
/**
* Concatenates the observable sequences obtained by running the specified result selector for each element in source.
* There is an alias for this method called 'forIn' for browsers 0) {
work = state.q.shift();
} else {
state.isAcquired = false;
return;
}
var m1 = new SingleAssignmentDisposable();
state.d.add(m1);
m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
recurse([state, self]);
}
ExpandObservable.prototype._ensureActive = function (state) {
var isOwner = false;
if (state.q.length > 0) {
isOwner = !state.isAcquired;
state.isAcquired = true;
}
isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
};
ExpandObservable.prototype.subscribeCore = function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
state = {
q: [],
m: m,
d: d,
activeCount: 0,
isAcquired: false,
o: o
};
state.q.push(this.source);
state.activeCount++;
this._ensureActive(state);
return d;
};
return ExpandObservable;
}(ObservableBase));
var ExpandObserver = (function(__super__) {
inherits(ExpandObserver, __super__);
function ExpandObserver(state, parent, m1) {
this._s = state;
this._p = parent;
this._m1 = m1;
__super__.call(this);
}
ExpandObserver.prototype.next = function (x) {
this._s.o.onNext(x);
var result = tryCatch(this._p._fn)(x);
if (result === errorObj) { return this._s.o.onError(result.e); }
this._s.q.push(result);
this._s.activeCount++;
this._p._ensureActive(this._s);
};
ExpandObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ExpandObserver.prototype.completed = function () {
this._s.d.remove(this._m1);
this._s.activeCount--;
this._s.activeCount === 0 && this._s.o.onCompleted();
};
return ExpandObserver;
}(AbstractObserver));
/**
* Expands an observable sequence by recursively invoking selector.
*
* @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
* @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
* @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
*/
observableProto.expand = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new ExpandObservable(this, selector, scheduler);
};
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ForkJoinObservable = (function (__super__) {
inherits(ForkJoinObservable, __super__);
function ForkJoinObservable(sources, cb) {
this._sources = sources;
this._cb = cb;
__super__.call(this);
}
ForkJoinObservable.prototype.subscribeCore = function (o) {
if (this._sources.length === 0) {
o.onCompleted();
return disposableEmpty;
}
var count = this._sources.length;
var state = {
finished: false,
hasResults: new Array(count),
hasCompleted: new Array(count),
results: new Array(count)
};
var subscriptions = new CompositeDisposable();
for (var i = 0, len = this._sources.length; i < len; i++) {
var source = this._sources[i];
isPromise(source) && (source = observableFromPromise(source));
subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
}
return subscriptions;
};
return ForkJoinObservable;
}(ObservableBase));
var ForkJoinObserver = (function(__super__) {
inherits(ForkJoinObserver, __super__);
function ForkJoinObserver(o, s, i, cb, subs) {
this._o = o;
this._s = s;
this._i = i;
this._cb = cb;
this._subs = subs;
__super__.call(this);
}
ForkJoinObserver.prototype.next = function (x) {
if (!this._s.finished) {
this._s.hasResults[this._i] = true;
this._s.results[this._i] = x;
}
};
ForkJoinObserver.prototype.error = function (e) {
this._s.finished = true;
this._o.onError(e);
this._subs.dispose();
};
ForkJoinObserver.prototype.completed = function () {
if (!this._s.finished) {
if (!this._s.hasResults[this._i]) {
return this._o.onCompleted();
}
this._s.hasCompleted[this._i] = true;
for (var i = 0; i < this._s.results.length; i++) {
if (!this._s.hasCompleted[i]) { return; }
}
this._s.finished = true;
var res = tryCatch(this._cb).apply(null, this._s.results);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
this._o.onCompleted();
}
};
return ForkJoinObserver;
}(AbstractObserver));
/**
* Runs all observable sequences in parallel and collect their last elements.
*
* @example
* 1 - res = Rx.Observable.forkJoin([obs1, obs2]);
* 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...);
* @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences.
*/
Observable.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new ForkJoinObservable(args, resultSelector);
};
/**
* Runs two observable sequences in parallel and combines their last elemenets.
* @param {Observable} second Second observable sequence.
* @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences.
* @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences.
*/
observableProto.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return Observable.forkJoin.apply(null, args);
};
/**
* Comonadic bind operator.
* @param {Function} selector A transform function to apply to each element.
* @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
* @returns {Observable} An observable sequence which results from the comonadic bind operation.
*/
observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
var source = this;
return observableDefer(function () {
var chain;
return source
.map(function (x) {
var curr = new ChainObservable(x);
chain && chain.onNext(x);
chain = curr;
return curr;
})
.tap(
noop,
function (e) { chain && chain.onError(e); },
function () { chain && chain.onCompleted(); }
)
.observeOn(scheduler)
.map(selector);
}, source);
};
var ChainObservable = (function (__super__) {
inherits(ChainObservable, __super__);
function ChainObservable(head) {
__super__.call(this);
this.head = head;
this.tail = new AsyncSubject();
}
addProperties(ChainObservable.prototype, Observer, {
_subscribe: function (o) {
var g = new CompositeDisposable();
g.add(currentThreadScheduler.schedule(this, function (_, self) {
o.onNext(self.head);
g.add(self.tail.mergeAll().subscribe(o));
}));
return g;
},
onCompleted: function () {
this.onNext(Observable.empty());
},
onError: function (e) {
this.onNext(Observable['throw'](e));
},
onNext: function (v) {
this.tail.onNext(v);
this.tail.onCompleted();
}
});
return ChainObservable;
}(Observable));
var SwitchFirstObservable = (function (__super__) {
inherits(SwitchFirstObservable, __super__);
function SwitchFirstObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
return SwitchFirstObservable;
}(ObservableBase));
var SwitchFirstObserver = (function(__super__) {
inherits(SwitchFirstObserver, __super__);
function SwitchFirstObserver(state) {
this._s = state;
__super__.call(this);
}
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = observableFromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
inherits(InnerObserver, __super__);
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
return SwitchFirstObserver;
}(AbstractObserver));
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
observableProto.switchFirst = function () {
return new SwitchFirstObservable(this);
};
observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
};
observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-experimental-compat/package.json
================================================
{
"name": "rx-lite-experimental-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with experimental functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.experimental.compat.js"
},
"browser": {
"index.js": "rx.lite.experimental.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.experimental.compat.js"
}
================================================
FILE: modules/rx-lite-experimental-compat/readme.md
================================================
# RxJS Experimental Compat Module #
The Reactive Extensions for JavaScript has a number of operators that are considered experimental and not ready for mainstream usage. This includes imperative operators such as `if`, `case`, `for`, `while`, `doWhile` as well as operators such as `forkJoin`. This requires `rx.lite.compat.js` from the [`rx-lite-compat`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-experimental-compat
$ npm install -g rx-lite-experimental-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-experimental-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`case | switchCase`](../../doc/api/core/operators/case.md)
- [`for | forIn`](../../doc/api/core/operators/for.md)
- [`forkJoin`](../../doc/api/core/operators/forkjoin.md)
- [`if | ifThen`](../../doc/api/core/operators/if.md)
- [`while | whileDo`](../../doc/api/core/operators/while.md)
### `Observable Instance Methods`
- [`doWhile`](/api/core/operators/dowhile.md)
- [`expand`](../../doc/api/core/operators/expand.md)
- [`forkJoin`](../../doc/api/core/operators/forkjoinproto.md)
- [`let | letBind`](../../doc/api/core/operators/let.md)
- [`manySelect`](../../doc/api/core/operators/manyselect.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-experimental-compat/rx.lite.experimental.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
FlatMapObservable = Rx.FlatMapObservable,
observableConcat = Observable.concat,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
disposableEmpty = Rx.Disposable.empty,
CompositeDisposable = Rx.CompositeDisposable,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Enumerable = Rx.internals.Enumerable,
enumerableOf = Enumerable.of,
currentThreadScheduler = Rx.Scheduler.currentThread,
AsyncSubject = Rx.AsyncSubject,
Observer = Rx.Observer,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
helpers = Rx.helpers,
noop = helpers.noop,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
var WhileEnumerable = (function(__super__) {
inherits(WhileEnumerable, __super__);
function WhileEnumerable(c, s) {
this.c = c;
this.s = s;
}
WhileEnumerable.prototype[$iterator$] = function () {
var self = this;
return {
next: function () {
return self.c() ?
{ done: false, value: self.s } :
{ done: true, value: void 0 };
}
};
};
return WhileEnumerable;
}(Enumerable));
function enumerableWhile(condition, source) {
return new WhileEnumerable(condition, source);
}
/**
* Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions.
* This operator allows for a fluent style of writing queries that use the same sequence multiple times.
*
* @param {Function} selector Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
observableProto.letBind = observableProto['let'] = function (func) {
return func(this);
};
/**
* Determines whether an observable collection contains values.
*
* @example
* 1 - res = Rx.Observable.if(condition, obs1);
* 2 - res = Rx.Observable.if(condition, obs1, obs2);
* 3 - res = Rx.Observable.if(condition, obs1, scheduler);
* @param {Function} condition The condition which determines if the thenSource or elseSource will be run.
* @param {Observable} thenSource The observable sequence or Promise that will be run if the condition function returns true.
* @param {Observable} [elseSource] The observable sequence or Promise that will be run if the condition function returns false. If this is not provided, it defaults to Rx.Observabe.Empty with the specified scheduler.
* @returns {Observable} An observable sequence which is either the thenSource or elseSource.
*/
Observable['if'] = function (condition, thenSource, elseSourceOrScheduler) {
return observableDefer(function () {
elseSourceOrScheduler || (elseSourceOrScheduler = observableEmpty());
isPromise(thenSource) && (thenSource = observableFromPromise(thenSource));
isPromise(elseSourceOrScheduler) && (elseSourceOrScheduler = observableFromPromise(elseSourceOrScheduler));
// Assume a scheduler for empty only
typeof elseSourceOrScheduler.now === 'function' && (elseSourceOrScheduler = observableEmpty(elseSourceOrScheduler));
return condition() ? thenSource : elseSourceOrScheduler;
});
};
/**
* Concatenates the observable sequences obtained by running the specified result selector for each element in source.
* There is an alias for this method called 'forIn' for browsers 0) {
work = state.q.shift();
} else {
state.isAcquired = false;
return;
}
var m1 = new SingleAssignmentDisposable();
state.d.add(m1);
m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
recurse([state, self]);
}
ExpandObservable.prototype._ensureActive = function (state) {
var isOwner = false;
if (state.q.length > 0) {
isOwner = !state.isAcquired;
state.isAcquired = true;
}
isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
};
ExpandObservable.prototype.subscribeCore = function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
state = {
q: [],
m: m,
d: d,
activeCount: 0,
isAcquired: false,
o: o
};
state.q.push(this.source);
state.activeCount++;
this._ensureActive(state);
return d;
};
return ExpandObservable;
}(ObservableBase));
var ExpandObserver = (function(__super__) {
inherits(ExpandObserver, __super__);
function ExpandObserver(state, parent, m1) {
this._s = state;
this._p = parent;
this._m1 = m1;
__super__.call(this);
}
ExpandObserver.prototype.next = function (x) {
this._s.o.onNext(x);
var result = tryCatch(this._p._fn)(x);
if (result === errorObj) { return this._s.o.onError(result.e); }
this._s.q.push(result);
this._s.activeCount++;
this._p._ensureActive(this._s);
};
ExpandObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ExpandObserver.prototype.completed = function () {
this._s.d.remove(this._m1);
this._s.activeCount--;
this._s.activeCount === 0 && this._s.o.onCompleted();
};
return ExpandObserver;
}(AbstractObserver));
/**
* Expands an observable sequence by recursively invoking selector.
*
* @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
* @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
* @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
*/
observableProto.expand = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new ExpandObservable(this, selector, scheduler);
};
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ForkJoinObservable = (function (__super__) {
inherits(ForkJoinObservable, __super__);
function ForkJoinObservable(sources, cb) {
this._sources = sources;
this._cb = cb;
__super__.call(this);
}
ForkJoinObservable.prototype.subscribeCore = function (o) {
if (this._sources.length === 0) {
o.onCompleted();
return disposableEmpty;
}
var count = this._sources.length;
var state = {
finished: false,
hasResults: new Array(count),
hasCompleted: new Array(count),
results: new Array(count)
};
var subscriptions = new CompositeDisposable();
for (var i = 0, len = this._sources.length; i < len; i++) {
var source = this._sources[i];
isPromise(source) && (source = observableFromPromise(source));
subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
}
return subscriptions;
};
return ForkJoinObservable;
}(ObservableBase));
var ForkJoinObserver = (function(__super__) {
inherits(ForkJoinObserver, __super__);
function ForkJoinObserver(o, s, i, cb, subs) {
this._o = o;
this._s = s;
this._i = i;
this._cb = cb;
this._subs = subs;
__super__.call(this);
}
ForkJoinObserver.prototype.next = function (x) {
if (!this._s.finished) {
this._s.hasResults[this._i] = true;
this._s.results[this._i] = x;
}
};
ForkJoinObserver.prototype.error = function (e) {
this._s.finished = true;
this._o.onError(e);
this._subs.dispose();
};
ForkJoinObserver.prototype.completed = function () {
if (!this._s.finished) {
if (!this._s.hasResults[this._i]) {
return this._o.onCompleted();
}
this._s.hasCompleted[this._i] = true;
for (var i = 0; i < this._s.results.length; i++) {
if (!this._s.hasCompleted[i]) { return; }
}
this._s.finished = true;
var res = tryCatch(this._cb).apply(null, this._s.results);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
this._o.onCompleted();
}
};
return ForkJoinObserver;
}(AbstractObserver));
/**
* Runs all observable sequences in parallel and collect their last elements.
*
* @example
* 1 - res = Rx.Observable.forkJoin([obs1, obs2]);
* 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...);
* @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences.
*/
Observable.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new ForkJoinObservable(args, resultSelector);
};
/**
* Runs two observable sequences in parallel and combines their last elemenets.
* @param {Observable} second Second observable sequence.
* @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences.
* @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences.
*/
observableProto.forkJoin = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return Observable.forkJoin.apply(null, args);
};
/**
* Comonadic bind operator.
* @param {Function} selector A transform function to apply to each element.
* @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
* @returns {Observable} An observable sequence which results from the comonadic bind operation.
*/
observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
var source = this;
return observableDefer(function () {
var chain;
return source
.map(function (x) {
var curr = new ChainObservable(x);
chain && chain.onNext(x);
chain = curr;
return curr;
})
.tap(
noop,
function (e) { chain && chain.onError(e); },
function () { chain && chain.onCompleted(); }
)
.observeOn(scheduler)
.map(selector);
}, source);
};
var ChainObservable = (function (__super__) {
inherits(ChainObservable, __super__);
function ChainObservable(head) {
__super__.call(this);
this.head = head;
this.tail = new AsyncSubject();
}
addProperties(ChainObservable.prototype, Observer, {
_subscribe: function (o) {
var g = new CompositeDisposable();
g.add(currentThreadScheduler.schedule(this, function (_, self) {
o.onNext(self.head);
g.add(self.tail.mergeAll().subscribe(o));
}));
return g;
},
onCompleted: function () {
this.onNext(Observable.empty());
},
onError: function (e) {
this.onNext(Observable['throw'](e));
},
onNext: function (v) {
this.tail.onNext(v);
this.tail.onCompleted();
}
});
return ChainObservable;
}(Observable));
var SwitchFirstObservable = (function (__super__) {
inherits(SwitchFirstObservable, __super__);
function SwitchFirstObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
return SwitchFirstObservable;
}(ObservableBase));
var SwitchFirstObserver = (function(__super__) {
inherits(SwitchFirstObserver, __super__);
function SwitchFirstObserver(state) {
this._s = state;
__super__.call(this);
}
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = observableFromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
inherits(InnerObserver, __super__);
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
return SwitchFirstObserver;
}(AbstractObserver));
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
observableProto.switchFirst = function () {
return new SwitchFirstObservable(this);
};
observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
};
observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-extras/package.json
================================================
{
"name": "rx-lite-extras",
"title": "Reactive Extensions for JavaScript (RxJS) Lite",
"description": "Lightweight library extras for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.extras.js"
},
"browser": {
"index.js": "rx.lite.extras.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.extras.js"
}
================================================
FILE: modules/rx-lite-extras/readme.md
================================================
# RxJS Lite Extras #
The Reactive Extensions for JavaScript's lite extras are the operators that are found on `rx.js` and but not available in `rx.lite.js`. By adding this file, you will have full access to all operators and thus makes including other files such as `rx.time.js`, `rx.joinpatterns.js` and others easier.
## Getting Started
There are a number of ways to get started with RxJS. The files are available on [cdnjs](http://cdnjs.com/libraries/rxjs/) and [jsDelivr](http://www.jsdelivr.com/#!rxjs).
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-extras
$ npm install -g rx-lite-extras
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-extras');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`amb`](../../doc/api/core/operators/amb.md)
- [`generate`](../../core/operators/generate.md)
- [`onErrorResumeNext`](../../doc/api/core/operators/onerrorresumenext.md)
- [`using`](../../doc/api/core/ooperators/using.md)
### `Observable Instance Methods`
- [`amb`](../../doc/api/core/operators/ambproto.md)
- [`bufferWithCount`](../../doc/api/core/operators/bufferwithcount.md)
- [`distinct`](../../doc/api/core/operators/distinct.md)
- [`observeOn`](../../doc/api/core/operators/observeon.md)
- [`onErrorResumeNext`](../../doc/api/core/operators/onerrorresumenext.md)
- [`subscribeOn`](../../doc/api/core/operators/subscribeon.md)
- [`takeLastBuffer`](../../doc/api/core/operators/takelastbuffer.md)
- [`windowWithCount`](../../doc/api/core/operators/windowwithcount.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-extras/rx.lite.extras.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
observableNever = Observable.never,
observableThrow = Observable['throw'],
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AnonymousObserver = Rx.AnonymousObserver,
notificationCreateOnNext = Rx.Notification.createOnNext,
notificationCreateOnError = Rx.Notification.createOnError,
notificationCreateOnCompleted = Rx.Notification.createOnCompleted,
Observer = Rx.Observer,
observerCreate = Observer.create,
AbstractObserver = Rx.internals.AbstractObserver,
Subject = Rx.Subject,
internals = Rx.internals,
helpers = Rx.helpers,
ScheduledObserver = internals.ScheduledObserver,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
disposableEmpty = Rx.Disposable.empty,
immediateScheduler = Rx.Scheduler.immediate,
defaultKeySerializer = helpers.defaultKeySerializer,
addRef = Rx.internals.addRef,
identity = helpers.identity,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
inherits = internals.inherits,
bindCallback = internals.bindCallback,
noop = helpers.noop,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
*
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var handlerFunc = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return handlerFunc(notificationCreateOnNext(x));
}, function (e) {
return handlerFunc(notificationCreateOnError(e));
}, function () {
return handlerFunc(notificationCreateOnCompleted());
});
};
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var source = this;
return new AnonymousObserver(
function (x) { source.onNext(x); },
function (e) { source.onError(e); },
function () { source.onCompleted(); }
);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var UsingObservable = (function (__super__) {
inherits(UsingObservable, __super__);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
__super__.call(this);
}
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = disposableEmpty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(observableThrow(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(observableThrow(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
return UsingObservable;
}(ObservableBase));
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
Observable.using = function (resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
/**
* Propagates the observable sequence or Promise that reacts first.
* @param {Observable} rightSource Second observable sequence or Promise.
* @returns {Observable} {Observable} An observable sequence that surfaces either of the given sequences, whichever reacted first.
*/
observableProto.amb = function (rightSource) {
var leftSource = this;
return new AnonymousObservable(function (observer) {
var choice,
leftChoice = 'L', rightChoice = 'R',
leftSubscription = new SingleAssignmentDisposable(),
rightSubscription = new SingleAssignmentDisposable();
isPromise(rightSource) && (rightSource = observableFromPromise(rightSource));
function choiceL() {
if (!choice) {
choice = leftChoice;
rightSubscription.dispose();
}
}
function choiceR() {
if (!choice) {
choice = rightChoice;
leftSubscription.dispose();
}
}
var leftSubscribe = observerCreate(
function (left) {
choiceL();
choice === leftChoice && observer.onNext(left);
},
function (e) {
choiceL();
choice === leftChoice && observer.onError(e);
},
function () {
choiceL();
choice === leftChoice && observer.onCompleted();
}
);
var rightSubscribe = observerCreate(
function (right) {
choiceR();
choice === rightChoice && observer.onNext(right);
},
function (e) {
choiceR();
choice === rightChoice && observer.onError(e);
},
function () {
choiceR();
choice === rightChoice && observer.onCompleted();
}
);
leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));
rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));
return new BinaryDisposable(leftSubscription, rightSubscription);
});
};
function amb(p, c) { return p.amb(c); }
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
Observable.amb = function () {
var acc = observableNever(), items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(items);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
for (var i = 0, len = items.length; i < len; i++) {
acc = amb(acc, items[i]);
}
return acc;
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence
* can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`)
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source.
*/
observableProto.singleInstance = function() {
var source = this, hasObservable = false, observable;
function getObservable() {
if (!hasObservable) {
hasObservable = true;
observable = source['finally'](function() { hasObservable = false; }).publish().refCount();
}
return observable;
}
return new AnonymousObservable(function(o) {
return getObservable().subscribe(o);
});
};
return Rx;
}));
================================================
FILE: modules/rx-lite-extras-compat/package.json
================================================
{
"name": "rx-lite-extras-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Lite",
"description": "Lightweight IE6 compatible library extras for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.extras.compat.js"
},
"browser": {
"index.js": "rx.lite.extras.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.extras.compat.js"
}
================================================
FILE: modules/rx-lite-extras-compat/readme.md
================================================
# RxJS Lite Compatibility Extras #
The Reactive Extensions for JavaScript's lite extras are the operators that are found on `rx.compat.js` and but not available in `rx.lite.compat.js`. By adding this file, you will have full access to all operators and thus makes including other files such as `rx.time.js`, `rx.joinpatterns.js` and others easier as well as having support for older browsers which do not support ES5 functionality.
## Getting Started
There are a number of ways to get started with RxJS. The files are available on [cdnjs](http://cdnjs.com/libraries/rxjs/) and [jsDelivr](http://www.jsdelivr.com/#!rxjs).
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-extras-compat
$ npm install -g rx-lite-extras-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-extras-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`amb`](../../doc/api/core/operators/amb.md)
- [`generate`](../../core/operators/generate.md)
- [`onErrorResumeNext`](../../doc/api/core/operators/onerrorresumenext.md)
- [`using`](../../doc/api/core/ooperators/using.md)
### `Observable Instance Methods`
- [`amb`](../../doc/api/core/operators/ambproto.md)
- [`bufferWithCount`](../../doc/api/core/operators/bufferwithcount.md)
- [`distinct`](../../doc/api/core/operators/distinct.md)
- [`observeOn`](../../doc/api/core/operators/observeon.md)
- [`onErrorResumeNext`](../../doc/api/core/operators/onerrorresumenext.md)
- [`subscribeOn`](../../doc/api/core/operators/subscribeon.md)
- [`takeLastBuffer`](../../doc/api/core/operators/takelastbuffer.md)
- [`windowWithCount`](../../doc/api/core/operators/windowwithcount.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-extras-compat/rx.lite.extras.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
observableNever = Observable.never,
observableThrow = Observable['throw'],
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AnonymousObserver = Rx.AnonymousObserver,
notificationCreateOnNext = Rx.Notification.createOnNext,
notificationCreateOnError = Rx.Notification.createOnError,
notificationCreateOnCompleted = Rx.Notification.createOnCompleted,
Observer = Rx.Observer,
observerCreate = Observer.create,
AbstractObserver = Rx.internals.AbstractObserver,
Subject = Rx.Subject,
internals = Rx.internals,
helpers = Rx.helpers,
ScheduledObserver = internals.ScheduledObserver,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
disposableEmpty = Rx.Disposable.empty,
immediateScheduler = Rx.Scheduler.immediate,
defaultKeySerializer = helpers.defaultKeySerializer,
addRef = Rx.internals.addRef,
identity = helpers.identity,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
inherits = internals.inherits,
bindCallback = internals.bindCallback,
noop = helpers.noop,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
*
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var handlerFunc = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return handlerFunc(notificationCreateOnNext(x));
}, function (e) {
return handlerFunc(notificationCreateOnError(e));
}, function () {
return handlerFunc(notificationCreateOnCompleted());
});
};
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var source = this;
return new AnonymousObserver(
function (x) { source.onNext(x); },
function (e) { source.onError(e); },
function () { source.onCompleted(); }
);
};
var ObserveOnObservable = (function (__super__) {
inherits(ObserveOnObservable, __super__);
function ObserveOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
ObserveOnObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ObserveOnObserver(this._s, o));
};
return ObserveOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
*
* This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
* that require to be run on a scheduler, use subscribeOn.
*
* @param {Scheduler} scheduler Scheduler to notify observers on.
* @returns {Observable} The source sequence whose observations happen on the specified scheduler.
*/
observableProto.observeOn = function (scheduler) {
return new ObserveOnObservable(this, scheduler);
};
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
var GenerateObservable = (function (__super__) {
inherits(GenerateObservable, __super__);
function GenerateObservable(state, cndFn, itrFn, resFn, s) {
this._initialState = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
var hasResult = tryCatch(state.self._cndFn)(state.newState);
if (hasResult === errorObj) { return state.o.onError(hasResult.e); }
if (hasResult) {
var result = tryCatch(state.self._resFn)(state.newState);
if (result === errorObj) { return state.o.onError(result.e); }
state.o.onNext(result);
recurse(state);
} else {
state.o.onCompleted();
}
}
GenerateObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
first: true,
newState: this._initialState
};
return this._s.scheduleRecursive(state, scheduleRecursive);
};
return GenerateObservable;
}(ObservableBase));
/**
* Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages.
*
* @example
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
* var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread.
* @returns {Observable} The generated sequence.
*/
Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new GenerateObservable(initialState, condition, iterate, resultSelector, scheduler);
};
var UsingObservable = (function (__super__) {
inherits(UsingObservable, __super__);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
__super__.call(this);
}
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = disposableEmpty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(observableThrow(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(observableThrow(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
return UsingObservable;
}(ObservableBase));
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
Observable.using = function (resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
/**
* Propagates the observable sequence or Promise that reacts first.
* @param {Observable} rightSource Second observable sequence or Promise.
* @returns {Observable} {Observable} An observable sequence that surfaces either of the given sequences, whichever reacted first.
*/
observableProto.amb = function (rightSource) {
var leftSource = this;
return new AnonymousObservable(function (observer) {
var choice,
leftChoice = 'L', rightChoice = 'R',
leftSubscription = new SingleAssignmentDisposable(),
rightSubscription = new SingleAssignmentDisposable();
isPromise(rightSource) && (rightSource = observableFromPromise(rightSource));
function choiceL() {
if (!choice) {
choice = leftChoice;
rightSubscription.dispose();
}
}
function choiceR() {
if (!choice) {
choice = rightChoice;
leftSubscription.dispose();
}
}
var leftSubscribe = observerCreate(
function (left) {
choiceL();
choice === leftChoice && observer.onNext(left);
},
function (e) {
choiceL();
choice === leftChoice && observer.onError(e);
},
function () {
choiceL();
choice === leftChoice && observer.onCompleted();
}
);
var rightSubscribe = observerCreate(
function (right) {
choiceR();
choice === rightChoice && observer.onNext(right);
},
function (e) {
choiceR();
choice === rightChoice && observer.onError(e);
},
function () {
choiceR();
choice === rightChoice && observer.onCompleted();
}
);
leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));
rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));
return new BinaryDisposable(leftSubscription, rightSubscription);
});
};
function amb(p, c) { return p.amb(c); }
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
Observable.amb = function () {
var acc = observableNever(), items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(items);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
for (var i = 0, len = items.length; i < len; i++) {
acc = amb(acc, items[i]);
}
return acc;
};
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @param {Observable} second Second observable sequence used to produce results after the first sequence terminates.
* @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally.
*/
observableProto.onErrorResumeNext = function (second) {
if (!second) { throw new Error('Second observable is required'); }
return onErrorResumeNext([this, second]);
};
var OnErrorResumeNextObservable = (function(__super__) {
inherits(OnErrorResumeNextObservable, __super__);
function OnErrorResumeNextObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.pos < state.sources.length) {
var current = state.sources[state.pos++];
isPromise(current) && (current = observableFromPromise(current));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(current.subscribe(new OnErrorResumeNextObserver(state, recurse)));
} else {
state.o.onCompleted();
}
}
OnErrorResumeNextObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable(),
state = {pos: 0, subscription: subscription, o: o, sources: this.sources },
cancellable = immediateScheduler.scheduleRecursive(state, scheduleMethod);
return new BinaryDisposable(subscription, cancellable);
};
return OnErrorResumeNextObservable;
}(ObservableBase));
var OnErrorResumeNextObserver = (function(__super__) {
inherits(OnErrorResumeNextObserver, __super__);
function OnErrorResumeNextObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
__super__.call(this);
}
OnErrorResumeNextObserver.prototype.next = function (x) { this._state.o.onNext(x); };
OnErrorResumeNextObserver.prototype.error = function () { this._recurse(this._state); };
OnErrorResumeNextObserver.prototype.completed = function () { this._recurse(this._state); };
return OnErrorResumeNextObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated normally or by an exception with the next observable sequence.
* @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally.
*/
var onErrorResumeNext = Observable.onErrorResumeNext = function () {
var sources = [];
if (Array.isArray(arguments[0])) {
sources = arguments[0];
} else {
var len = arguments.length;
sources = new Array(len);
for(var i = 0; i < len; i++) { sources[i] = arguments[i]; }
}
return new OnErrorResumeNextObservable(sources);
};
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on element count information.
* @param {Number} count Length of each window.
* @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithCount = observableProto.windowCount = function (count, skip) {
var source = this;
+count || (count = 0);
Math.abs(count) === Infinity && (count = 0);
if (count <= 0) { throw new ArgumentOutOfRangeError(); }
skip == null && (skip = count);
+skip || (skip = 0);
Math.abs(skip) === Infinity && (skip = 0);
if (skip <= 0) { throw new ArgumentOutOfRangeError(); }
return new AnonymousObservable(function (observer) {
var m = new SingleAssignmentDisposable(),
refCountDisposable = new RefCountDisposable(m),
n = 0,
q = [];
function createWindow () {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
createWindow();
m.setDisposable(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
var c = n - count + 1;
c >= 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence
* can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`)
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source.
*/
observableProto.singleInstance = function() {
var source = this, hasObservable = false, observable;
function getObservable() {
if (!hasObservable) {
hasObservable = true;
observable = source['finally'](function() { hasObservable = false; }).publish().refCount();
}
return observable;
}
return new AnonymousObservable(function(o) {
return getObservable().subscribe(o);
});
};
return Rx;
}));
================================================
FILE: modules/rx-lite-joinpatterns/package.json
================================================
{
"name": "rx-lite-joinpatterns",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with join pattern functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.joinpatterns.js"
},
"browser": {
"index.js": "rx.lite.joinpatterns.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.joinpatterns.js"
}
================================================
FILE: modules/rx-lite-joinpatterns/readme.md
================================================
# RxJS Join Patterns Module #
The Reactive Extensions for JavaScript also supports join calculus in that you can easily create patterns for when certain observable sequences fire. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-joinpatterns
$ npm install -g rx-lite-joinpatterns
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-joinpatterns');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`when`](../../doc/api/core/operators/when.md)
### `Observable Instance Methods`
- [`and`](../../doc/api/core/operators/and.md)
### `Pattern Instance Methods`
- [`thenDo`](../../doc/api/core/operators/thendo.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-joinpatterns/rx.lite.joinpatterns.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
observableThrow = Observable.throwError,
observerCreate = Rx.Observer.create,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
AbstractObserver = Rx.internals.AbstractObserver,
noop = Rx.helpers.noop,
inherits = Rx.internals.inherits,
isFunction = Rx.helpers.isFunction;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this.patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this.patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
function Plan(expression, selector) {
this.expression = expression;
this.selector = selector;
}
function handleOnError(o) { return function (e) { o.onError(e); }; }
function handleOnNext(self, observer) {
return function onNext () {
var result = tryCatch(self.selector).apply(self, arguments);
if (result === errorObj) { return observer.onError(result.e); }
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [], errHandler = handleOnError(observer);
for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this.joinObserverArray = joinObserverArray;
this.onNext = onNext;
this.onCompleted = onCompleted;
this.joinObservers = new Map();
for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
var joinObserver = this.joinObserverArray[i];
this.joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this.joinObservers.forEach(function (v) { v.queue.shift(); });
};
ActivePlan.prototype.match = function () {
var i, len, hasValues = true;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
if (this.joinObserverArray[i].queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
firstValues.push(this.joinObserverArray[i].queue[0]);
this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this.onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this.onNext.apply(this, values);
}
}
};
var JoinObserver = (function (__super__) {
inherits(JoinObserver, __super__);
function JoinObserver(source, onError) {
__super__.call(this);
this.source = source;
this.onError = onError;
this.queue = [];
this.activePlans = [];
this.subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
var JoinObserverPrototype = JoinObserver.prototype;
JoinObserverPrototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this.onError(notification.error);
}
this.queue.push(notification);
var activePlans = this.activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserverPrototype.error = noop;
JoinObserverPrototype.completed = noop;
JoinObserverPrototype.addActivePlan = function (activePlan) {
this.activePlans.push(activePlan);
};
JoinObserverPrototype.subscribe = function () {
this.subscription.setDisposable(this.source.materialize().subscribe(this));
};
JoinObserverPrototype.removeActivePlan = function (activePlan) {
this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
this.activePlans.length === 0 && this.dispose();
};
JoinObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this.subscription.dispose();
}
};
return JoinObserver;
} (AbstractObserver));
/**
* Creates a pattern that matches when both observable sequences have an available value.
*
* @param right Observable sequence to match with the current sequence.
* @return {Pattern} Pattern object that matches when both observable sequences have an available value.
*/
observableProto.and = function (right) {
return new Pattern([this, right]);
};
/**
* Matches when the observable sequence has an available value and projects the value.
*
* @param {Function} selector Selector that will be invoked for values in the source sequence.
* @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
observableProto.thenDo = function (selector) {
return new Pattern([this]).thenDo(selector);
};
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
Observable.when = function () {
var len = arguments.length, plans;
if (Array.isArray(arguments[0])) {
plans = arguments[0];
} else {
plans = new Array(len);
for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
}
return new AnonymousObservable(function (o) {
var activePlans = [],
externalSubscriptions = new Map();
var outObserver = observerCreate(
function (x) { o.onNext(x); },
function (err) {
externalSubscriptions.forEach(function (v) { v.onError(err); });
o.onError(err);
},
function (x) { o.onCompleted(); }
);
try {
for (var i = 0, len = plans.length; i < len; i++) {
activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return observableThrow(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
});
};
return Rx;
}));
================================================
FILE: modules/rx-lite-joinpatterns-compat/package.json
================================================
{
"name": "rx-lite-joinpatterns-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with join pattern functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.joinpatterns.compat.js"
},
"browser": {
"index.js": "rx.lite.joinpatterns.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.joinpatterns.compat.js"
}
================================================
FILE: modules/rx-lite-joinpatterns-compat/readme.md
================================================
# RxJS Join Patterns Compat Module #
The Reactive Extensions for JavaScript also supports join calculus in that you can easily create patterns for when certain observable sequences fire. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-joinpatterns-compat
$ npm install -g rx-lite-joinpatterns-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-joinpatterns');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`when`](../../doc/api/core/operators/when.md)
### `Observable Instance Methods`
- [`and`](../../doc/api/core/operators/and.md)
### `Pattern Instance Methods`
- [`thenDo`](../../doc/api/core/operators/thendo.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-joinpatterns-compat/rx.lite.joinpatterns.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
observableThrow = Observable.throwError,
observerCreate = Rx.Observer.create,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
AbstractObserver = Rx.internals.AbstractObserver,
noop = Rx.helpers.noop,
inherits = Rx.internals.inherits,
isFunction = Rx.helpers.isFunction;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this.patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this.patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
function Plan(expression, selector) {
this.expression = expression;
this.selector = selector;
}
function handleOnError(o) { return function (e) { o.onError(e); }; }
function handleOnNext(self, observer) {
return function onNext () {
var result = tryCatch(self.selector).apply(self, arguments);
if (result === errorObj) { return observer.onError(result.e); }
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [], errHandler = handleOnError(observer);
for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this.joinObserverArray = joinObserverArray;
this.onNext = onNext;
this.onCompleted = onCompleted;
this.joinObservers = new Map();
for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
var joinObserver = this.joinObserverArray[i];
this.joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this.joinObservers.forEach(function (v) { v.queue.shift(); });
};
ActivePlan.prototype.match = function () {
var i, len, hasValues = true;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
if (this.joinObserverArray[i].queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
firstValues.push(this.joinObserverArray[i].queue[0]);
this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this.onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this.onNext.apply(this, values);
}
}
};
var JoinObserver = (function (__super__) {
inherits(JoinObserver, __super__);
function JoinObserver(source, onError) {
__super__.call(this);
this.source = source;
this.onError = onError;
this.queue = [];
this.activePlans = [];
this.subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
var JoinObserverPrototype = JoinObserver.prototype;
JoinObserverPrototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this.onError(notification.error);
}
this.queue.push(notification);
var activePlans = this.activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserverPrototype.error = noop;
JoinObserverPrototype.completed = noop;
JoinObserverPrototype.addActivePlan = function (activePlan) {
this.activePlans.push(activePlan);
};
JoinObserverPrototype.subscribe = function () {
this.subscription.setDisposable(this.source.materialize().subscribe(this));
};
JoinObserverPrototype.removeActivePlan = function (activePlan) {
this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
this.activePlans.length === 0 && this.dispose();
};
JoinObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this.subscription.dispose();
}
};
return JoinObserver;
} (AbstractObserver));
/**
* Creates a pattern that matches when both observable sequences have an available value.
*
* @param right Observable sequence to match with the current sequence.
* @return {Pattern} Pattern object that matches when both observable sequences have an available value.
*/
observableProto.and = function (right) {
return new Pattern([this, right]);
};
/**
* Matches when the observable sequence has an available value and projects the value.
*
* @param {Function} selector Selector that will be invoked for values in the source sequence.
* @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
observableProto.thenDo = function (selector) {
return new Pattern([this]).thenDo(selector);
};
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
Observable.when = function () {
var len = arguments.length, plans;
if (Array.isArray(arguments[0])) {
plans = arguments[0];
} else {
plans = new Array(len);
for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
}
return new AnonymousObservable(function (o) {
var activePlans = [],
externalSubscriptions = new Map();
var outObserver = observerCreate(
function (x) { o.onNext(x); },
function (err) {
externalSubscriptions.forEach(function (v) { v.onError(err); });
o.onError(err);
},
function (x) { o.onCompleted(); }
);
try {
for (var i = 0, len = plans.length; i < len; i++) {
activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return observableThrow(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
});
};
return Rx;
}));
================================================
FILE: modules/rx-lite-testing/package.json
================================================
{
"name": "rx-lite-testing",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with testing functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.testing.js"
},
"browser": {
"index.js": "rx.lite.testing.js"
},
"dependencies": {
"rx-lite-virtualtime": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.testing.js"
}
================================================
FILE: modules/rx-lite-testing/readme.md
================================================
# RxJS Testing Module #
The Reactive Extensions for JavaScript has a built-in mechanism for testing all operators which allows for mocking absolute and relative time with ease. This requires `rx.lite.virtualtime.js` from the [`rx-lite-virtualtime`](https://www.npmjs.com/package/rx-virtualtime) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-testing
$ npm install -g rx-lite-testing
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-testing');
```
### In a Browser:
```html
```
## Included Classes ##
### Testing Classes
- [`Rx.ReactiveTest`](../../doc/api/testing/reactivetest.md)
- [`Rx.Recorded`](../../doc/api/testing/recorded.md)
- [`Rx.Subscription`](../../doc/api/testing/subscription.md)
- [`Rx.TestScheduler`](../../doc/api/testing/testscheduler.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-testing/rx.lite.testing.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.virtualtime'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-virtualtime'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Notification = Rx.Notification,
VirtualTimeScheduler = Rx.VirtualTimeScheduler,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
inherits = Rx.internals.inherits,
defaultComparer = Rx.internals.isEqual;
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
return Rx;
}));
================================================
FILE: modules/rx-lite-testing-compat/package.json
================================================
{
"name": "rx-lite-testing-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with testing functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.testing.compat.js"
},
"browser": {
"index.js": "rx.lite.testing.compat.js"
},
"dependencies": {
"rx-virtualtime-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.testing.compat.js"
}
================================================
FILE: modules/rx-lite-testing-compat/readme.md
================================================
# RxJS Testing Compat Module #
The Reactive Extensions for JavaScript has a built-in mechanism for testing all operators which allows for mocking absolute and relative time with ease. This requires `rx.lite.virtualtime.js` from the [`rx-lite-virtualtime`](https://www.npmjs.com/package/rx-virtualtime) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-testing-compat
$ npm install -g rx-lite-testing-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-testing-compat');
```
### In a Browser:
```html
```
## Included Classes ##
### Testing Classes
- [`Rx.ReactiveTest`](../../doc/api/testing/reactivetest.md)
- [`Rx.Recorded`](../../doc/api/testing/recorded.md)
- [`Rx.Subscription`](../../doc/api/testing/subscription.md)
- [`Rx.TestScheduler`](../../doc/api/testing/testscheduler.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-testing-compat/rx.lite.testing.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.virtualtime.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-virtualtime-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Notification = Rx.Notification,
VirtualTimeScheduler = Rx.VirtualTimeScheduler,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
inherits = Rx.internals.inherits,
defaultComparer = Rx.internals.isEqual;
function OnNextPredicate(predicate) {
this.predicate = predicate;
}
OnNextPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'N') { return false; }
return this.predicate(other.value);
};
function OnErrorPredicate(predicate) {
this.predicate = predicate;
}
OnErrorPredicate.prototype.equals = function (other) {
if (other === this) { return true; }
if (other == null) { return false; }
if (other.kind !== 'E') { return false; }
return this.predicate(other.error);
};
var ReactiveTest = Rx.ReactiveTest = {
/** Default virtual time used for creation of observable sequences in unit tests. */
created: 100,
/** Default virtual time used to subscribe to observable sequences in unit tests. */
subscribed: 200,
/** Default virtual time used to dispose subscriptions in unit tests. */
disposed: 1000,
/**
* Factory method for an OnNext notification record at a given time with a given value or a predicate function.
*
* 1 - ReactiveTest.onNext(200, 42);
* 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; });
*
* @param ticks Recorded virtual time the OnNext notification occurs.
* @param value Recorded value stored in the OnNext notification or a predicate.
* @return Recorded OnNext notification.
*/
onNext: function (ticks, value) {
return typeof value === 'function' ?
new Recorded(ticks, new OnNextPredicate(value)) :
new Recorded(ticks, Notification.createOnNext(value));
},
/**
* Factory method for an OnError notification record at a given time with a given error.
*
* 1 - ReactiveTest.onNext(200, new Error('error'));
* 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; });
*
* @param ticks Recorded virtual time the OnError notification occurs.
* @param exception Recorded exception stored in the OnError notification.
* @return Recorded OnError notification.
*/
onError: function (ticks, error) {
return typeof error === 'function' ?
new Recorded(ticks, new OnErrorPredicate(error)) :
new Recorded(ticks, Notification.createOnError(error));
},
/**
* Factory method for an OnCompleted notification record at a given time.
*
* @param ticks Recorded virtual time the OnCompleted notification occurs.
* @return Recorded OnCompleted notification.
*/
onCompleted: function (ticks) {
return new Recorded(ticks, Notification.createOnCompleted());
},
/**
* Factory method for a subscription record based on a given subscription and disposal time.
*
* @param start Virtual time indicating when the subscription was created.
* @param end Virtual time indicating when the subscription was disposed.
* @return Subscription object.
*/
subscribe: function (start, end) {
return new Subscription(start, end);
}
};
/**
* Creates a new object recording the production of the specified value at the given virtual time.
*
* @constructor
* @param {Number} time Virtual time the value was produced on.
* @param {Mixed} value Value that was produced.
* @param {Function} comparer An optional comparer.
*/
var Recorded = Rx.Recorded = function (time, value, comparer) {
this.time = time;
this.value = value;
this.comparer = comparer || defaultComparer;
};
/**
* Checks whether the given recorded object is equal to the current instance.
*
* @param {Recorded} other Recorded object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Recorded.prototype.equals = function (other) {
return this.time === other.time && this.comparer(this.value, other.value);
};
/**
* Returns a string representation of the current Recorded value.
*
* @returns {String} String representation of the current Recorded value.
*/
Recorded.prototype.toString = function () {
return this.value.toString() + '@' + this.time;
};
/**
* Creates a new subscription object with the given virtual subscription and unsubscription time.
*
* @constructor
* @param {Number} subscribe Virtual time at which the subscription occurred.
* @param {Number} unsubscribe Virtual time at which the unsubscription occurred.
*/
var Subscription = Rx.Subscription = function (start, end) {
this.subscribe = start;
this.unsubscribe = end || Number.MAX_VALUE;
};
/**
* Checks whether the given subscription is equal to the current instance.
* @param other Subscription object to check for equality.
* @returns {Boolean} true if both objects are equal; false otherwise.
*/
Subscription.prototype.equals = function (other) {
return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe;
};
/**
* Returns a string representation of the current Subscription value.
* @returns {String} String representation of the current Subscription value.
*/
Subscription.prototype.toString = function () {
return '(' + this.subscribe + ', ' + (this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe) + ')';
};
var MockDisposable = Rx.MockDisposable = function (scheduler) {
this.scheduler = scheduler;
this.disposes = [];
this.disposes.push(this.scheduler.clock);
};
MockDisposable.prototype.dispose = function () {
this.disposes.push(this.scheduler.clock);
};
var MockObserver = (function (__super__) {
inherits(MockObserver, __super__);
function MockObserver(scheduler) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = [];
}
var MockObserverPrototype = MockObserver.prototype;
MockObserverPrototype.onNext = function (value) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value)));
};
MockObserverPrototype.onError = function (e) {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(e)));
};
MockObserverPrototype.onCompleted = function () {
this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted()));
};
return MockObserver;
})(Observer);
function MockPromise(scheduler, messages) {
var self = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
var message = this.messages[i],
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = self.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
MockPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var newPromise;
var observer = Rx.Observer.create(
function (x) {
var retValue = onResolved(x);
if (retValue && typeof retValue.then === 'function') {
newPromise = retValue;
} else {
var ticks = self.scheduler.clock;
newPromise = new MockPromise(self.scheduler, [Rx.ReactiveTest.onNext(ticks, undefined), Rx.ReactiveTest.onCompleted(ticks)]);
}
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
},
function (err) {
onRejected(err);
var idx = self.observers.indexOf(observer);
self.observers.splice(idx, 1);
self.subscriptions[index] = new Subscription(self.subscriptions[index].subscribe, self.scheduler.clock);
}
);
this.observers.push(observer);
return newPromise || new MockPromise(this.scheduler, this.messages);
};
var HotObservable = (function (__super__) {
inherits(HotObservable, __super__);
function HotObservable(scheduler, messages) {
__super__.call(this);
var message, notification, observable = this;
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
this.observers = [];
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
scheduler.scheduleAbsolute(null, message.time, function () {
var obs = observable.observers.slice(0);
for (var j = 0, jLen = obs.length; j < jLen; j++) {
innerNotification.accept(obs[j]);
}
return disposableEmpty;
});
})(notification);
}
}
HotObservable.prototype._subscribe = function (o) {
var observable = this;
this.observers.push(o);
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
return disposableCreate(function () {
var idx = observable.observers.indexOf(o);
observable.observers.splice(idx, 1);
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
});
};
return HotObservable;
})(Observable);
var ColdObservable = (function (__super__) {
inherits(ColdObservable, __super__);
function ColdObservable(scheduler, messages) {
__super__.call(this);
this.scheduler = scheduler;
this.messages = messages;
this.subscriptions = [];
}
ColdObservable.prototype._subscribe = function (o) {
var message, notification, observable = this;
this.subscriptions.push(new Subscription(this.scheduler.clock));
var index = this.subscriptions.length - 1;
var d = new CompositeDisposable();
for (var i = 0, len = this.messages.length; i < len; i++) {
message = this.messages[i];
notification = message.value;
(function (innerNotification) {
d.add(observable.scheduler.scheduleRelative(null, message.time, function () {
innerNotification.accept(o);
return disposableEmpty;
}));
})(notification);
}
return disposableCreate(function () {
observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock);
d.dispose();
});
};
return ColdObservable;
})(Observable);
/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */
Rx.TestScheduler = (function (__super__) {
inherits(TestScheduler, __super__);
function baseComparer(x, y) {
return x > y ? 1 : (x < y ? -1 : 0);
}
function TestScheduler() {
__super__.call(this, 0, baseComparer);
}
/**
* Schedules an action to be executed at the specified virtual time.
*
* @param state State passed to the action to be executed.
* @param dueTime Absolute virtual time at which to execute the action.
* @param action Action to be executed.
* @return Disposable object used to cancel the scheduled action (best effort).
*/
TestScheduler.prototype.scheduleAbsolute = function (state, dueTime, action) {
dueTime <= this.clock && (dueTime = this.clock + 1);
return __super__.prototype.scheduleAbsolute.call(this, state, dueTime, action);
};
/**
* Adds a relative virtual time to an absolute virtual time value.
*
* @param absolute Absolute virtual time value.
* @param relative Relative virtual time value to add.
* @return Resulting absolute virtual time sum value.
*/
TestScheduler.prototype.add = function (absolute, relative) {
return absolute + relative;
};
/**
* Converts the absolute virtual time value to a DateTimeOffset value.
*
* @param absolute Absolute virtual time value to convert.
* @return Corresponding DateTimeOffset value.
*/
TestScheduler.prototype.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
*
* @param timeSpan TimeSpan value to convert.
* @return Corresponding relative virtual time value.
*/
TestScheduler.prototype.toRelativeTime = function (timeSpan) {
return timeSpan;
};
/**
* Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription.
*
* @param create Factory method to create an observable sequence.
* @param created Virtual time at which to invoke the factory to create an observable sequence.
* @param subscribed Virtual time at which to subscribe to the created observable sequence.
* @param disposed Virtual time at which to dispose the subscription.
* @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active.
*/
TestScheduler.prototype.startScheduler = function (createFn, settings) {
settings || (settings = {});
settings.created == null && (settings.created = ReactiveTest.created);
settings.subscribed == null && (settings.subscribed = ReactiveTest.subscribed);
settings.disposed == null && (settings.disposed = ReactiveTest.disposed);
var observer = this.createObserver(), source, subscription;
this.scheduleAbsolute(null, settings.created, function () {
source = createFn();
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.subscribed, function () {
subscription = source.subscribe(observer);
return disposableEmpty;
});
this.scheduleAbsolute(null, settings.disposed, function () {
subscription.dispose();
return disposableEmpty;
});
this.start();
return observer;
};
/**
* Creates a hot observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified absolute virtual times.
* @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createHotObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new HotObservable(this, args);
};
/**
* Creates a cold observable using the specified timestamped notification messages either as an array or arguments.
* @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time.
* @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications.
*/
TestScheduler.prototype.createColdObservable = function () {
var len = arguments.length, args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(len);
for (var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
return new ColdObservable(this, args);
};
/**
* Creates a resolved promise with the given value and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} value The value to yield at the given tick.
* @returns {MockPromise} A mock Promise which fulfills with the given value.
*/
TestScheduler.prototype.createResolvedPromise = function (ticks, value) {
return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]);
};
/**
* Creates a rejected promise with the given reason and ticks
* @param {Number} ticks The absolute time of the resolution.
* @param {Any} reason The reason for rejection to yield at the given tick.
* @returns {MockPromise} A mock Promise which rejects with the given reason.
*/
TestScheduler.prototype.createRejectedPromise = function (ticks, reason) {
return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]);
};
/**
* Creates an observer that records received notification messages and timestamps those.
* @return Observer that can be used to assert the timing of received notifications.
*/
TestScheduler.prototype.createObserver = function () {
return new MockObserver(this);
};
return TestScheduler;
})(VirtualTimeScheduler);
return Rx;
}));
================================================
FILE: modules/rx-lite-time/package.json
================================================
{
"name": "rx-lite-time",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with time-based functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.time.js"
},
"browser": {
"index.js": "rx.lite.time.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.time.js"
}
================================================
FILE: modules/rx-lite-time/readme.md
================================================
# RxJS Time Module #
The Reactive Extensions for JavaScript, as it is a library that deals with events over time, naturally has a large number of operators that allow the creation of sequences at given timers, in addition to capturing time stamp and time interval information. In addition, you can also check for timeouts on your operations. This also supports windows and buffers with time. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-time
$ npm install -g rx-lite-time
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-time');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`generateWithAbsoluteTime`](../../doc/api/core/operators/generatewithabsolutetime.md)
- [`generateWithRelativeTime`](../../doc/api/core/operators/generatewithrelativetime.md)
### `Observable Instance Methods`
- [`bufferWithTime`](../../doc/api/core/operators/bufferwithtime.md)
- [`bufferWithTimeOrCount`](../../doc/api/core/operators/bufferwithtimeorcount.md)
- [`debounceWithSelector`](../../doc/api/core/operators/debouncewithselector.md)
- [`delaySubscription`](../api/core/operators/delaysubscription.md)
- [`skipLastWithTime`](../../doc/api/core/operators/skiplastwithtime.md)
- [`takeLastBufferWithTime`](../../doc/api/core/operators/takelastbufferwithtime.md)
- [`takeLastWithTime`](../../doc/api/core/operators/takelastwithtime.md)
- [`throttle`](../../doc/api/core/operators/throttle.md)
- [`throttleWithTimeout`](../../doc/api/core/operators/debounce.md)
- [`timeInterval`](../../doc/api/core/operators/timeinterval.md)
- [`timeoutWithSelector`](../../doc/api/core/operators/timeoutwithselector.md)
- [`timestamp`](../../doc/api/core/operators/timestamp.md)
- [`windowWithTime`](../../doc/api/core/operators/windowwithtime.md)
- [`windowWithTimeOrCount`](../../doc/api/core/operators/windowwithtimeorcount.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-time/rx.lite.time.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Refernces
var inherits = Rx.internals.inherits,
AbstractObserver = Rx.internals.AbstractObserver,
Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
observableNever = Observable.never,
observableThrow = Observable['throw'],
observableFromArray = Observable.fromArray,
defaultScheduler = Rx.Scheduler['default'],
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
Subject = Rx.Subject,
addRef = Rx.internals.addRef,
normalizeTime = Rx.Scheduler.normalize,
helpers = Rx.helpers,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
* @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTime = observableProto.windowTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
var source = this, timeShift;
timeShiftOrScheduler == null && (timeShift = timeSpan);
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (typeof timeShiftOrScheduler === 'number') {
timeShift = timeShiftOrScheduler;
} else if (isScheduler(timeShiftOrScheduler)) {
timeShift = timeSpan;
scheduler = timeShiftOrScheduler;
}
return new AnonymousObservable(function (observer) {
var groupDisposable,
nextShift = timeShift,
nextSpan = timeSpan,
q = [],
refCountDisposable,
timerD = new SerialDisposable(),
totalTime = 0;
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable);
function createTimer () {
var m = new SingleAssignmentDisposable(),
isSpan = false,
isShift = false;
timerD.setDisposable(m);
if (nextSpan === nextShift) {
isSpan = true;
isShift = true;
} else if (nextSpan < nextShift) {
isSpan = true;
} else {
isShift = true;
}
var newTotalTime = isSpan ? nextSpan : nextShift,
ts = newTotalTime - totalTime;
totalTime = newTotalTime;
if (isSpan) {
nextSpan += timeShift;
}
if (isShift) {
nextShift += timeShift;
}
m.setDisposable(scheduler.scheduleFuture(null, ts, function () {
if (isShift) {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
isSpan && q.shift().onCompleted();
createTimer();
}));
};
q.push(new Subject());
observer.onNext(addRef(q[0], refCountDisposable));
createTimer();
groupDisposable.add(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
},
function (e) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onError(e); }
observer.onError(e);
},
function () {
for (var i = 0, len = q.length; i < len; i++) { q[i].onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
/**
* Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a window.
* @param {Number} count Maximum element count of a window.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTimeOrCount = observableProto.windowTimeOrCount = function (timeSpan, count, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (observer) {
var timerD = new SerialDisposable(),
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable),
n = 0,
windowId = 0,
s = new Subject();
function createTimer(id) {
var m = new SingleAssignmentDisposable();
timerD.setDisposable(m);
m.setDisposable(scheduler.scheduleFuture(null, timeSpan, function () {
if (id !== windowId) { return; }
n = 0;
var newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
createTimer(newId);
}));
}
observer.onNext(addRef(s, refCountDisposable));
createTimer(0);
groupDisposable.add(source.subscribe(
function (x) {
var newId = 0, newWindow = false;
s.onNext(x);
if (++n === count) {
newWindow = true;
n = 0;
newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
}
newWindow && createTimer(newId);
},
function (e) {
s.onError(e);
observer.onError(e);
}, function () {
s.onCompleted();
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
* @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
* @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTime = observableProto.bufferTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
return this.windowWithTime(timeSpan, timeShiftOrScheduler, scheduler).flatMap(toArray);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a buffer.
* @param {Number} count Maximum element count of a buffer.
* @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTimeOrCount = observableProto.bufferTimeOrCount = function (timeSpan, count, scheduler) {
return this.windowWithTimeOrCount(timeSpan, count, scheduler).flatMap(toArray);
};
var TimeIntervalObservable = (function (__super__) {
inherits(TimeIntervalObservable, __super__);
function TimeIntervalObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimeIntervalObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimeIntervalObserver(o, this._s));
};
return TimeIntervalObservable;
}(ObservableBase));
var TimeIntervalObserver = (function (__super__) {
inherits(TimeIntervalObserver, __super__);
function TimeIntervalObserver(o, s) {
this._o = o;
this._s = s;
this._l = s.now();
__super__.call(this);
}
TimeIntervalObserver.prototype.next = function (x) {
var now = this._s.now(), span = now - this._l;
this._l = now;
this._o.onNext({ value: x, interval: span });
};
TimeIntervalObserver.prototype.error = function (e) { this._o.onError(e); };
TimeIntervalObserver.prototype.completed = function () { this._o.onCompleted(); };
return TimeIntervalObserver;
}(AbstractObserver));
/**
* Records the time interval between consecutive values in an observable sequence.
*
* @example
* 1 - res = source.timeInterval();
* 2 - res = source.timeInterval(Rx.Scheduler.timeout);
*
* @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence with time interval information on values.
*/
observableProto.timeInterval = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimeIntervalObservable(this, scheduler);
};
var GenerateAbsoluteObservable = (function (__super__) {
inherits(GenerateAbsoluteObservable, __super__);
function GenerateAbsoluteObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateAbsoluteObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, new Date(this._s.now()), scheduleRecursive);
};
return GenerateAbsoluteObservable;
}(ObservableBase));
/**
* GenerateAbsolutes an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithAbsoluteTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return new Date(); }
* });
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateAbsoluteObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var GenerateRelativeObservable = (function (__super__) {
inherits(GenerateRelativeObservable, __super__);
function GenerateRelativeObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateRelativeObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, 0, scheduleRecursive);
};
return GenerateRelativeObservable;
}(ObservableBase));
/**
* Generates an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithRelativeTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return 500; }
* );
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateRelativeObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var DelaySubscription = (function(__super__) {
inherits(DelaySubscription, __super__);
function DelaySubscription(source, dt, s) {
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DelaySubscription.prototype.subscribeCore = function (o) {
var d = new SerialDisposable();
d.setDisposable(this._s.scheduleFuture([this.source, o, d], this._dt, scheduleMethod));
return d;
};
function scheduleMethod(s, state) {
var source = state[0], o = state[1], d = state[2];
d.setDisposable(source.subscribe(o));
}
return DelaySubscription;
}(ObservableBase));
/**
* Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.delaySubscription(5000); // 5s
* 2 - res = source.delaySubscription(5000, Rx.Scheduler.default); // 5 seconds
*
* @param {Number} dueTime Relative or absolute time shift of the subscription.
* @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delaySubscription = function (dueTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new DelaySubscription(this, dueTime, scheduler);
};
var SkipLastWithTimeObservable = (function (__super__) {
inherits(SkipLastWithTimeObservable, __super__);
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
return SkipLastWithTimeObservable;
}(ObservableBase));
var SkipLastWithTimeObserver = (function (__super__) {
inherits(SkipLastWithTimeObserver, __super__);
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
__super__.call(this);
}
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
return SkipLastWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for skipping elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
*/
observableProto.skipLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipLastWithTimeObservable(this, duration, scheduler);
};
var TakeLastWithTimeObservable = (function (__super__) {
inherits(TakeLastWithTimeObservable, __super__);
function TakeLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
TakeLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeLastWithTimeObserver(o, this._d, this._s));
};
return TakeLastWithTimeObservable;
}(ObservableBase));
var TakeLastWithTimeObserver = (function (__super__) {
inherits(TakeLastWithTimeObserver, __super__);
function TakeLastWithTimeObserver(o, d, s) {
this._o = o;
this._d = d;
this._s = s;
this._q = [];
__super__.call(this);
}
TakeLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._q.shift();
}
};
TakeLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0) {
var next = this._q.shift();
if (now - next.interval <= this._d) { this._o.onNext(next.value); }
}
this._o.onCompleted();
};
return TakeLastWithTimeObserver;
}(AbstractObserver));
/**
* Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeLastWithTimeObservable(this, duration, scheduler);
};
/**
* Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastBufferWithTime = function (duration, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (o) {
var q = [];
return source.subscribe(function (x) {
var now = scheduler.now();
q.push({ interval: now, value: x });
while (q.length > 0 && now - q[0].interval >= duration) {
q.shift();
}
}, function (e) { o.onError(e); }, function () {
var now = scheduler.now(), res = [];
while (q.length > 0) {
var next = q.shift();
now - next.interval <= duration && res.push(next.value);
}
o.onNext(res);
o.onCompleted();
});
}, source);
};
var TakeWithTimeObservable = (function (__super__) {
inherits(TakeWithTimeObservable, __super__);
function TakeWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
function scheduleMethod(s, o) {
o.onCompleted();
}
TakeWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(o, this._d, scheduleMethod),
this.source.subscribe(o)
);
};
return TakeWithTimeObservable;
}(ObservableBase));
/**
* Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.takeWithTime(5000, [optional scheduler]);
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
*/
observableProto.takeWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeWithTimeObservable(this, duration, scheduler);
};
var SkipWithTimeObservable = (function (__super__) {
inherits(SkipWithTimeObservable, __super__);
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
__super__.call(this);
}
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
return SkipWithTimeObservable;
}(ObservableBase));
var SkipWithTimeObserver = (function (__super__) {
inherits(SkipWithTimeObserver, __super__);
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
* @description
* Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
* This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
* may not execute immediately, despite the zero due time.
*
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
* @param {Number} duration Duration for skipping elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
*/
observableProto.skipWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipWithTimeObservable(this, duration, scheduler);
};
var SkipUntilWithTimeObservable = (function (__super__) {
inherits(SkipUntilWithTimeObservable, __super__);
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
__super__.call(this);
}
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
return SkipUntilWithTimeObservable;
}(ObservableBase));
var SkipUntilWithTimeObserver = (function (__super__) {
inherits(SkipUntilWithTimeObserver, __super__);
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipUntilWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
*
* @examples
* 1 - res = source.skipUntilWithTime(new Date(), [scheduler]);
* 2 - res = source.skipUntilWithTime(5000, [scheduler]);
* @param {Date|Number} startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped until the specified start time.
*/
observableProto.skipUntilWithTime = function (startTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipUntilWithTimeObservable(this, startTime, scheduler);
};
/**
* Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
* @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
* @param {Scheduler} [scheduler] Scheduler to run the timer on.
* @returns {Observable} An observable sequence with the elements taken until the specified end time.
*/
observableProto.takeUntilWithTime = function (endTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var source = this;
return new AnonymousObservable(function (o) {
return new BinaryDisposable(
scheduler.scheduleFuture(o, endTime, function (_, o) { o.onCompleted(); }),
source.subscribe(o));
}, source);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-time-compat/package.json
================================================
{
"name": "rx-lite-time-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with time-based functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.time.compat.js"
},
"browser": {
"index.js": "rx.lite.time.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.time.compat.js"
}
================================================
FILE: modules/rx-lite-time-compat/readme.md
================================================
# RxJS Time Compat Module #
The Reactive Extensions for JavaScript, as it is a library that deals with events over time, naturally has a large number of operators that allow the creation of sequences at given timers, in addition to capturing time stamp and time interval information. In addition, you can also check for timeouts on your operations. This also supports windows and buffers with time. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-time
$ npm install -g rx-lite-time
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-time-compat');
```
### In a Browser:
```html
```
## Included Observable Operators ##
### `Observable Methods`
- [`generateWithAbsoluteTime`](../../doc/api/core/operators/generatewithabsolutetime.md)
- [`generateWithRelativeTime`](../../doc/api/core/operators/generatewithrelativetime.md)
### `Observable Instance Methods`
- [`bufferWithTime`](../../doc/api/core/operators/bufferwithtime.md)
- [`bufferWithTimeOrCount`](../../doc/api/core/operators/bufferwithtimeorcount.md)
- [`debounceWithSelector`](../../doc/api/core/operators/debouncewithselector.md)
- [`delaySubscription`](../api/core/operators/delaysubscription.md)
- [`skipLastWithTime`](../../doc/api/core/operators/skiplastwithtime.md)
- [`takeLastBufferWithTime`](../../doc/api/core/operators/takelastbufferwithtime.md)
- [`takeLastWithTime`](../../doc/api/core/operators/takelastwithtime.md)
- [`throttle`](../../doc/api/core/operators/throttle.md)
- [`throttleWithTimeout`](../../doc/api/core/operators/debounce.md)
- [`timeInterval`](../../doc/api/core/operators/timeinterval.md)
- [`timeoutWithSelector`](../../doc/api/core/operators/timeoutwithselector.md)
- [`timestamp`](../../doc/api/core/operators/timestamp.md)
- [`windowWithTime`](../../doc/api/core/operators/windowwithtime.md)
- [`windowWithTimeOrCount`](../../doc/api/core/operators/windowwithtimeorcount.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-time-compat/rx.lite.time.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Refernces
var inherits = Rx.internals.inherits,
AbstractObserver = Rx.internals.AbstractObserver,
Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
observableNever = Observable.never,
observableThrow = Observable['throw'],
observableFromArray = Observable.fromArray,
defaultScheduler = Rx.Scheduler['default'],
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
Subject = Rx.Subject,
addRef = Rx.internals.addRef,
normalizeTime = Rx.Scheduler.normalize,
helpers = Rx.helpers,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
* @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTime = observableProto.windowTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
var source = this, timeShift;
timeShiftOrScheduler == null && (timeShift = timeSpan);
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (typeof timeShiftOrScheduler === 'number') {
timeShift = timeShiftOrScheduler;
} else if (isScheduler(timeShiftOrScheduler)) {
timeShift = timeSpan;
scheduler = timeShiftOrScheduler;
}
return new AnonymousObservable(function (observer) {
var groupDisposable,
nextShift = timeShift,
nextSpan = timeSpan,
q = [],
refCountDisposable,
timerD = new SerialDisposable(),
totalTime = 0;
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable);
function createTimer () {
var m = new SingleAssignmentDisposable(),
isSpan = false,
isShift = false;
timerD.setDisposable(m);
if (nextSpan === nextShift) {
isSpan = true;
isShift = true;
} else if (nextSpan < nextShift) {
isSpan = true;
} else {
isShift = true;
}
var newTotalTime = isSpan ? nextSpan : nextShift,
ts = newTotalTime - totalTime;
totalTime = newTotalTime;
if (isSpan) {
nextSpan += timeShift;
}
if (isShift) {
nextShift += timeShift;
}
m.setDisposable(scheduler.scheduleFuture(null, ts, function () {
if (isShift) {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
isSpan && q.shift().onCompleted();
createTimer();
}));
};
q.push(new Subject());
observer.onNext(addRef(q[0], refCountDisposable));
createTimer();
groupDisposable.add(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
},
function (e) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onError(e); }
observer.onError(e);
},
function () {
for (var i = 0, len = q.length; i < len; i++) { q[i].onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
/**
* Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a window.
* @param {Number} count Maximum element count of a window.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTimeOrCount = observableProto.windowTimeOrCount = function (timeSpan, count, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (observer) {
var timerD = new SerialDisposable(),
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable),
n = 0,
windowId = 0,
s = new Subject();
function createTimer(id) {
var m = new SingleAssignmentDisposable();
timerD.setDisposable(m);
m.setDisposable(scheduler.scheduleFuture(null, timeSpan, function () {
if (id !== windowId) { return; }
n = 0;
var newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
createTimer(newId);
}));
}
observer.onNext(addRef(s, refCountDisposable));
createTimer(0);
groupDisposable.add(source.subscribe(
function (x) {
var newId = 0, newWindow = false;
s.onNext(x);
if (++n === count) {
newWindow = true;
n = 0;
newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
}
newWindow && createTimer(newId);
},
function (e) {
s.onError(e);
observer.onError(e);
}, function () {
s.onCompleted();
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
* @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
* @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTime = observableProto.bufferTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
return this.windowWithTime(timeSpan, timeShiftOrScheduler, scheduler).flatMap(toArray);
};
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a buffer.
* @param {Number} count Maximum element count of a buffer.
* @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTimeOrCount = observableProto.bufferTimeOrCount = function (timeSpan, count, scheduler) {
return this.windowWithTimeOrCount(timeSpan, count, scheduler).flatMap(toArray);
};
var TimeIntervalObservable = (function (__super__) {
inherits(TimeIntervalObservable, __super__);
function TimeIntervalObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimeIntervalObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimeIntervalObserver(o, this._s));
};
return TimeIntervalObservable;
}(ObservableBase));
var TimeIntervalObserver = (function (__super__) {
inherits(TimeIntervalObserver, __super__);
function TimeIntervalObserver(o, s) {
this._o = o;
this._s = s;
this._l = s.now();
__super__.call(this);
}
TimeIntervalObserver.prototype.next = function (x) {
var now = this._s.now(), span = now - this._l;
this._l = now;
this._o.onNext({ value: x, interval: span });
};
TimeIntervalObserver.prototype.error = function (e) { this._o.onError(e); };
TimeIntervalObserver.prototype.completed = function () { this._o.onCompleted(); };
return TimeIntervalObserver;
}(AbstractObserver));
/**
* Records the time interval between consecutive values in an observable sequence.
*
* @example
* 1 - res = source.timeInterval();
* 2 - res = source.timeInterval(Rx.Scheduler.timeout);
*
* @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence with time interval information on values.
*/
observableProto.timeInterval = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimeIntervalObservable(this, scheduler);
};
var GenerateAbsoluteObservable = (function (__super__) {
inherits(GenerateAbsoluteObservable, __super__);
function GenerateAbsoluteObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateAbsoluteObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, new Date(this._s.now()), scheduleRecursive);
};
return GenerateAbsoluteObservable;
}(ObservableBase));
/**
* GenerateAbsolutes an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithAbsoluteTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return new Date(); }
* });
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateAbsoluteObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var GenerateRelativeObservable = (function (__super__) {
inherits(GenerateRelativeObservable, __super__);
function GenerateRelativeObservable(state, cndFn, itrFn, resFn, timeFn, s) {
this._state = state;
this._cndFn = cndFn;
this._itrFn = itrFn;
this._resFn = resFn;
this._timeFn = timeFn;
this._s = s;
__super__.call(this);
}
function scheduleRecursive(state, recurse) {
state.hasResult && state.o.onNext(state.result);
if (state.first) {
state.first = false;
} else {
state.newState = tryCatch(state.self._itrFn)(state.newState);
if (state.newState === errorObj) { return state.o.onError(state.newState.e); }
}
state.hasResult = tryCatch(state.self._cndFn)(state.newState);
if (state.hasResult === errorObj) { return state.o.onError(state.hasResult.e); }
if (state.hasResult) {
state.result = tryCatch(state.self._resFn)(state.newState);
if (state.result === errorObj) { return state.o.onError(state.result.e); }
var time = tryCatch(state.self._timeFn)(state.newState);
if (time === errorObj) { return state.o.onError(time.e); }
recurse(state, time);
} else {
state.o.onCompleted();
}
}
GenerateRelativeObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
self: this,
newState: this._state,
first: true,
hasResult: false
};
return this._s.scheduleRecursiveFuture(state, 0, scheduleRecursive);
};
return GenerateRelativeObservable;
}(ObservableBase));
/**
* Generates an observable sequence by iterating a state from an initial state until the condition fails.
*
* @example
* res = source.generateWithRelativeTime(0,
* function (x) { return return true; },
* function (x) { return x + 1; },
* function (x) { return x; },
* function (x) { return 500; }
* );
*
* @param {Mixed} initialState Initial state.
* @param {Function} condition Condition to terminate generation (upon returning false).
* @param {Function} iterate Iteration step function.
* @param {Function} resultSelector Selector function for results produced in the sequence.
* @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds.
* @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used.
* @returns {Observable} The generated sequence.
*/
Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new GenerateRelativeObservable(initialState, condition, iterate, resultSelector, timeSelector, scheduler);
};
var DelaySubscription = (function(__super__) {
inherits(DelaySubscription, __super__);
function DelaySubscription(source, dt, s) {
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DelaySubscription.prototype.subscribeCore = function (o) {
var d = new SerialDisposable();
d.setDisposable(this._s.scheduleFuture([this.source, o, d], this._dt, scheduleMethod));
return d;
};
function scheduleMethod(s, state) {
var source = state[0], o = state[1], d = state[2];
d.setDisposable(source.subscribe(o));
}
return DelaySubscription;
}(ObservableBase));
/**
* Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.delaySubscription(5000); // 5s
* 2 - res = source.delaySubscription(5000, Rx.Scheduler.default); // 5 seconds
*
* @param {Number} dueTime Relative or absolute time shift of the subscription.
* @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delaySubscription = function (dueTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new DelaySubscription(this, dueTime, scheduler);
};
var SkipLastWithTimeObservable = (function (__super__) {
inherits(SkipLastWithTimeObservable, __super__);
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
return SkipLastWithTimeObservable;
}(ObservableBase));
var SkipLastWithTimeObserver = (function (__super__) {
inherits(SkipLastWithTimeObserver, __super__);
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
__super__.call(this);
}
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
return SkipLastWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for skipping elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
*/
observableProto.skipLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipLastWithTimeObservable(this, duration, scheduler);
};
var TakeLastWithTimeObservable = (function (__super__) {
inherits(TakeLastWithTimeObservable, __super__);
function TakeLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
TakeLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeLastWithTimeObserver(o, this._d, this._s));
};
return TakeLastWithTimeObservable;
}(ObservableBase));
var TakeLastWithTimeObserver = (function (__super__) {
inherits(TakeLastWithTimeObserver, __super__);
function TakeLastWithTimeObserver(o, d, s) {
this._o = o;
this._d = d;
this._s = s;
this._q = [];
__super__.call(this);
}
TakeLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._q.shift();
}
};
TakeLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0) {
var next = this._q.shift();
if (now - next.interval <= this._d) { this._o.onNext(next.value); }
}
this._o.onCompleted();
};
return TakeLastWithTimeObserver;
}(AbstractObserver));
/**
* Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeLastWithTimeObservable(this, duration, scheduler);
};
/**
* Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastBufferWithTime = function (duration, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (o) {
var q = [];
return source.subscribe(function (x) {
var now = scheduler.now();
q.push({ interval: now, value: x });
while (q.length > 0 && now - q[0].interval >= duration) {
q.shift();
}
}, function (e) { o.onError(e); }, function () {
var now = scheduler.now(), res = [];
while (q.length > 0) {
var next = q.shift();
now - next.interval <= duration && res.push(next.value);
}
o.onNext(res);
o.onCompleted();
});
}, source);
};
var TakeWithTimeObservable = (function (__super__) {
inherits(TakeWithTimeObservable, __super__);
function TakeWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
function scheduleMethod(s, o) {
o.onCompleted();
}
TakeWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(o, this._d, scheduleMethod),
this.source.subscribe(o)
);
};
return TakeWithTimeObservable;
}(ObservableBase));
/**
* Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.takeWithTime(5000, [optional scheduler]);
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
*/
observableProto.takeWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeWithTimeObservable(this, duration, scheduler);
};
var SkipWithTimeObservable = (function (__super__) {
inherits(SkipWithTimeObservable, __super__);
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
__super__.call(this);
}
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
return SkipWithTimeObservable;
}(ObservableBase));
var SkipWithTimeObserver = (function (__super__) {
inherits(SkipWithTimeObserver, __super__);
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
* @description
* Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
* This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
* may not execute immediately, despite the zero due time.
*
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
* @param {Number} duration Duration for skipping elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
*/
observableProto.skipWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipWithTimeObservable(this, duration, scheduler);
};
var SkipUntilWithTimeObservable = (function (__super__) {
inherits(SkipUntilWithTimeObservable, __super__);
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
__super__.call(this);
}
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
return SkipUntilWithTimeObservable;
}(ObservableBase));
var SkipUntilWithTimeObserver = (function (__super__) {
inherits(SkipUntilWithTimeObserver, __super__);
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipUntilWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
*
* @examples
* 1 - res = source.skipUntilWithTime(new Date(), [scheduler]);
* 2 - res = source.skipUntilWithTime(5000, [scheduler]);
* @param {Date|Number} startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped until the specified start time.
*/
observableProto.skipUntilWithTime = function (startTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipUntilWithTimeObservable(this, startTime, scheduler);
};
/**
* Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
* @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
* @param {Scheduler} [scheduler] Scheduler to run the timer on.
* @returns {Observable} An observable sequence with the elements taken until the specified end time.
*/
observableProto.takeUntilWithTime = function (endTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var source = this;
return new AnonymousObservable(function (o) {
return new BinaryDisposable(
scheduler.scheduleFuture(o, endTime, function (_, o) { o.onCompleted(); }),
source.subscribe(o));
}, source);
};
return Rx;
}));
================================================
FILE: modules/rx-lite-virtualtime/package.json
================================================
{
"name": "rx-lite-virtualtime",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight library with virtual time functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.virtualtime.js"
},
"browser": {
"index.js": "rx.lite.virtualtime.js"
},
"dependencies": {
"rx-lite": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.virtualtime.js"
}
================================================
FILE: modules/rx-lite-virtualtime/readme.md
================================================
# RxJS Virtual Time Module #
The Reactive Extensions for JavaScript supports a notion of virtual time, which allows you to mock time easily, or even run through historical data through the `HistoricalScheduler`. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-virtualtime
$ npm install -g rx-lite-virtualtime
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-virtualtime');
```
### In a Browser:
```html
```
## Included Classes ##
### Schedulers
- [`Rx.HistoricalScheduler`](../../doc/api/schedulers/historicalscheduler.md)
- [`Rx.VirtualTimeScheduler`](../../doc/api/schedulers/virtualtimescheduler.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-virtualtime/rx.lite.virtualtime.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
defaultSubComparer = Rx.helpers.defaultSubComparer,
notImplemented = Rx.helpers.notImplemented;
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
/** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
Rx.HistoricalScheduler = (function (__super__) {
inherits(HistoricalScheduler, __super__);
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function HistoricalScheduler(initialClock, comparer) {
var clock = initialClock == null ? 0 : initialClock;
var cmp = comparer || defaultSubComparer;
__super__.call(this, clock, cmp);
}
var HistoricalSchedulerProto = HistoricalScheduler.prototype;
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
HistoricalSchedulerProto.add = function (absolute, relative) {
return absolute + relative;
};
HistoricalSchedulerProto.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
* @memberOf HistoricalScheduler
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
HistoricalSchedulerProto.toRelativeTime = function (timeSpan) {
return timeSpan;
};
return HistoricalScheduler;
}(Rx.VirtualTimeScheduler));
return Rx;
}));
================================================
FILE: modules/rx-lite-virtualtime-compat/package.json
================================================
{
"name": "rx-lite-virtualtime-compat",
"title": "Reactive Extensions for JavaScript (RxJS) Async",
"description": "Lightweight older browser compatible library with virtual time functions for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"licenses": [
{
"type": "Apache License, Version 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
],
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "rx.lite.virtualtime.compat.js"
},
"browser": {
"index.js": "rx.lite.virtualtime.compat.js"
},
"dependencies": {
"rx-lite-compat": "*"
},
"devDependencies": {},
"keywords": [
"React",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "rx.lite.virtualtime.compat.js"
}
================================================
FILE: modules/rx-lite-virtualtime-compat/readme.md
================================================
# RxJS Virtual Time Compat Module #
The Reactive Extensions for JavaScript supports a notion of virtual time, which allows you to mock time easily, or even run through historical data through the `HistoricalScheduler`. This requires `rx.lite.js` from the [`rx-lite`](https://www.npmjs.com/package/rx-lite) NPM module. This module has support for older browsers which do not support ES5 functionality, hence the name `compat`.
## Getting Started
There are a number of ways to get started with RxJS.
### Installing with [NPM](https://npmjs.org/)
```bash`
$ npm install rx-lite-virtualtime-compat
$ npm install -g rx-lite-virtualtime-compat
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx-lite-virtualtime-compat');
```
### In a Browser:
```html
```
## Included Classes ##
### Schedulers
- [`Rx.HistoricalScheduler`](../../doc/api/schedulers/historicalscheduler.md)
- [`Rx.VirtualTimeScheduler`](../../doc/api/schedulers/virtualtimescheduler.md)
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: modules/rx-lite-virtualtime-compat/rx.lite.virtualtime.compat.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
// Aliases
var Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
defaultSubComparer = Rx.helpers.defaultSubComparer,
notImplemented = Rx.helpers.notImplemented;
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
/** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
Rx.HistoricalScheduler = (function (__super__) {
inherits(HistoricalScheduler, __super__);
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function HistoricalScheduler(initialClock, comparer) {
var clock = initialClock == null ? 0 : initialClock;
var cmp = comparer || defaultSubComparer;
__super__.call(this, clock, cmp);
}
var HistoricalSchedulerProto = HistoricalScheduler.prototype;
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
HistoricalSchedulerProto.add = function (absolute, relative) {
return absolute + relative;
};
HistoricalSchedulerProto.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
* @memberOf HistoricalScheduler
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
HistoricalSchedulerProto.toRelativeTime = function (timeSpan) {
return timeSpan;
};
return HistoricalScheduler;
}(Rx.VirtualTimeScheduler));
return Rx;
}));
================================================
FILE: modules/version.js
================================================
var fs = require('fs');
var execSync = require('child_process').execSync;
var files = fs.readdirSync(process.cwd());
for (var i = 0; i < files.length; i++) {
var file = files[i];
var stat = fs.statSync(file);
if (stat.isDirectory()) {
console.log('versioning %s', file);
execSync('cd '+ file + ' && npm version '+ process.argv[2] + ' && cd ..');
console.log('versioned %s', file);
}
}
================================================
FILE: nuget/RxJS-Aggregates/RxJS-Aggregates.nuspec
================================================
RxJS-AggregatesReactive Extensions for JavaScript - Aggregation Operations$version$Microsoft CorporationReactive Extensions for JavaScript library with aggregation event processing query operations.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-All/RxJS-All.nuspec
================================================
RxJS-AllReactive Extensions for JavaScript - All Libraries$version$Microsoft CorporationReactive Extensions for JavaScript libraries.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Async/RxJS-Async.nuspec
================================================
RxJS-AsyncReactive Extensions for JavaScript - Async-Based Operations$version$Microsoft CorporationReactive Extensions for JavaScript library with async-based event processing query operations.http://go.microsoft.com/fwlink/?LinkID=179929http://go.microsoft.com/fwlink/?LinkId=261274truehttp://go.microsoft.com/fwlink/?LinkID=265024en-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-BackPressure/RxJS-BackPressure.nuspec
================================================
RxJS-BackPressureReactive Extensions for JavaScript - BackPressure-Based Operations$version$Microsoft CorporationReactive Extensions for JavaScript library with async-based event processing query operations.http://go.microsoft.com/fwlink/?LinkID=179929http://go.microsoft.com/fwlink/?LinkId=261274truehttp://go.microsoft.com/fwlink/?LinkID=265024en-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Binding/RxJS-Binding.nuspec
================================================
RxJS-BindingReactive Extensions for JavaScript - Binding$version$Microsoft CorporationReactive Extensions for JavaScript library with binding operationrs.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Coincidence/RxJS-Coincidence.nuspec
================================================
RxJS-CoincidenceReactive Extensions for JavaScript - Coincidence$version$Microsoft CorporationReactive Extensions for JavaScript library with reactive coincidence join event processing query operations.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Complete/RxJS-Complete.nuspec
================================================
RxJS-MainReactive Extensions for JavaScript - Main Library$version$Microsoft CorporationReactive Extensions for JavaScript main library used to express complex event processing queries over observable sequences.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Experimental/RxJS-Experimental.nuspec
================================================
RxJS-ExperimentalReactive Extensions for JavaScript - Experimental$version$Microsoft CorporationReactive Extensions for JavaScript library with experimental operators.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-JoinPatterns/RxJS-JoinPatterns.nuspec
================================================
RxJS-JoinPatternsReactive Extensions for JavaScript - Join Patterns$version$Microsoft CorporationReactive Extensions for JavaScript library with join patterns event processing query operations.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Lite/RxJS-Lite.nuspec
================================================
RxJS-LiteReactive Extensions for JavaScript - Lite Library$version$Microsoft CorporationReactive Extensions for JavaScript main library used to express complex event processing queries over observable sequences.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Main/RxJS-Main.nuspec
================================================
RxJS-MainReactive Extensions for JavaScript - Main Library$version$Microsoft CorporationReactive Extensions for JavaScript main library used to express complex event processing queries over observable sequences.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Testing/RxJS-Testing.nuspec
================================================
RxJS-TestingReactive Extensions for JavaScript - Test Library$version$Microsoft CorporationReactive Extensions for JavaScript test library, used to write unit tests for complex event processing queries.http://rx.codeplex.comhttp://go.microsoft.com/fwlink/?LinkId=261274truehttp://www.apache.org/licenses/LICENSE-2.0.htmlen-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-Time/RxJS-Time.nuspec
================================================
RxJS-TimeReactive Extensions for JavaScript - Time-Based Operations$version$Microsoft CorporationReactive Extensions for JavaScript library with time-based event processing query operations.http://go.microsoft.com/fwlink/?LinkID=179929http://go.microsoft.com/fwlink/?LinkId=261274truehttp://go.microsoft.com/fwlink/?LinkID=265024en-USRx RxJS Reactive Extensions Observable
================================================
FILE: nuget/RxJS-VirtualTime/RxJS-VirtualTime.nuspec
================================================
RxJS-VirtualTimeReactive Extensions for JavaScript - Virtual Time-Based Schedulers$version$Microsoft CorporationReactive Extensions for JavaScript library with virtual time based schedulers.http://go.microsoft.com/fwlink/?LinkID=179929http://go.microsoft.com/fwlink/?LinkId=261274truehttp://go.microsoft.com/fwlink/?LinkID=265024en-USRx RxJS Reactive Extensions Observable
================================================
FILE: package.json
================================================
{
"name": "rx",
"title": "Reactive Extensions for JavaScript (RxJS)",
"description": "Library for composing asynchronous and event-based operations in JavaScript",
"version": "4.1.0",
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"author": {
"name": "Cloud Programmability Team",
"url": "https://github.com/Reactive-Extensions/RxJS/blob/master/authors.txt"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"license": "Apache-2.0",
"bugs": "https://github.com/Reactive-Extensions/RxJS/issues",
"jam": {
"main": "dist/rx.all.js"
},
"browser": {
"index.js": "./dist/rx.all.js"
},
"dependencies": {},
"devDependencies": {
"benchmark": "*",
"grunt-cli": "*",
"grunt": "*",
"grunt-contrib-copy": "*",
"grunt-contrib-jshint": "*",
"grunt-contrib-connect": "*",
"grunt-contrib-uglify": "*",
"grunt-contrib-concat": "*",
"grunt-contrib-qunit": "*",
"grunt-contrib-watch": "*",
"grunt-jscs": "*",
"load-grunt-tasks": "*"
},
"keywords": [
"LINQ",
"FRP",
"Reactive",
"Events",
"Rx",
"RxJS"
],
"main": "index.js",
"typings": "./ts/rx.all.d.ts",
"scripts": {
"test": "grunt"
}
}
================================================
FILE: readme.md
================================================
[](https://travis-ci.org/Reactive-Extensions/RxJS)
[](https://github.com/Reactive-Extensions/RxJS)
[](https://www.npmjs.com/package/rx)
[](https://www.npmjs.com/package/rx)
[](http://bower.io/search/?q=rxjs)
[](http://www.nuget.org/packages/RxJS-All/)
[](https://gitter.im/Reactive-Extensions/RxJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# NOTE: The latest version of RxJS can be found [here](https://github.com/reactivex/rxjs)
**[The Need to go Reactive](#the-need-to-go-reactive)** |
**[About the Reactive Extensions](#about-the-reactive-extensions)** |
**[Batteries Included](#batteries-included)** |
**[Why RxJS?](#why-rxjs)** |
**[Dive In!](#dive-in)** |
**[Resources](#resources)** |
**[Getting Started](#getting-started)** |
**[What about my libraries?](#what-about-my-libraries)** |
**[Compatibility](#compatibility)** |
**[Contributing](#contributing)** |
**[License](#license)**
# The Reactive Extensions for JavaScript (RxJS) 4.0... #
*...is a set of libraries to compose asynchronous and event-based programs using observable collections and [Array#extras](http://blogs.msdn.com/b/ie/archive/2010/12/13/ecmascript-5-part-2-array-extras.aspx) style composition in JavaScript*
The project is actively developed by [Microsoft](https://microsoft.com/), in collaboration with a community of open source developers.
## The Need to go Reactive ##
Applications, especially on the web have changed over the years from being a simple static page, to DHTML with animations, to the Ajax revolution. Each time, we're adding more complexity, more data, and asynchronous behavior to our applications. How do we manage it all? How do we scale it? By moving towards "Reactive Architectures" which are event-driven, resilient and responsive. With the Reactive Extensions, you have all the tools you need to help build these systems.
## About the Reactive Extensions ##
The Reactive Extensions for JavaScript (RxJS) is a set of libraries for composing asynchronous and event-based programs using observable sequences and fluent query operators that many of you already know by [Array#extras](http://blogs.msdn.com/b/ie/archive/2010/12/13/ecmascript-5-part-2-array-extras.aspx) in JavaScript. Using RxJS, developers represent asynchronous data streams with Observables, query asynchronous data streams using our many operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, RxJS = Observables + Operators + Schedulers.
Whether you are authoring a web-based application in JavaScript or a server-side application in Node.js, you have to deal with asynchronous and event-based programming. Although some patterns are emerging such as the Promise pattern, handling exceptions, cancellation, and synchronization is difficult and error-prone.
Using RxJS, you can represent multiple asynchronous data streams (that come from diverse sources, e.g., stock quote, tweets, computer events, web service requests, etc.), and subscribe to the event stream using the Observer object. The Observable notifies the subscribed Observer instance whenever an event occurs.
Because observable sequences are data streams, you can query them using standard query operators implemented by the Observable type. Thus you can filter, project, aggregate, compose and perform time-based operations on multiple events easily by using these operators. In addition, there are a number of other reactive stream specific operators that allow powerful queries to be written. Cancellation, exceptions, and synchronization are also handled gracefully by using the methods on the Observable object.
But the best news of all is that you already know how to program like this. Take for example the following JavaScript code, where we get some stock data and then manipulate and iterate the results.
```js
/* Get stock data somehow */
const source = getAsyncStockData();
const subscription = source
.filter(quote => quote.price > 30)
.map(quote => quote.price)
.forEach(price => console.log(`Prices higher than $30: ${price}`));
```
Now what if this data were to come as some sort of event, for example a stream, such as a WebSocket? Then we could pretty much write the same query to iterate our data, with very little change.
```js
/* Get stock data somehow */
const source = getAsyncStockData();
const subscription = source
.filter(quote => quote.price > 30)
.map(quote => quote.price)
.subscribe(
price => console.log(`Prices higher than $30: ${price}`),
err => console.log(`Something went wrong: ${err.message}`)
);
/* When we're done */
subscription.dispose();
```
The only difference is that we can handle the errors inline with our subscription. And when we're no longer interested in receiving the data as it comes streaming in, we call `dispose` on our subscription. Note the use of `subscribe` instead of `forEach`. We could also use `forEach` which is an alias for `subscribe` but we highly suggest you use `subscribe`.
## Batteries Included ##
Sure, there are a lot of libraries to get started with RxJS. Confused on where to get started? Start out with the complete set of operators with [`rx.all.js`](doc/libraries/main/rx.complete.md), then you can reduce it to the number of operators that you really need, and perhaps stick with something as small as [`rx.lite.js`](doc/libraries/lite/rx.lite.md). If you're an implementor of RxJS, then you can start out with [`rx.core.js`](doc/libraries/core/rx.core.md).
This set of libraries include:
### The complete library:
- [`rx.all.js`](doc/libraries/main/rx.complete.md)
### Main Libraries:
- [`rx.js`](doc/libraries/main/rx.md)
- [`rx.aggregates.js`](doc/libraries/main/rx.aggregates.md)
- [`rx.async.js`](doc/libraries/main/rx.async.md)
- [`rx.binding.js`](doc/libraries/main/rx.binding.md)
- [`rx.coincidence.js`](doc/libraries/main/rx.coincidence.md)
- [`rx.experimental.js`](doc/libraries/main/rx.experimental.md)
- [`rx.joinpatterns.js`](doc/libraries/main/rx.joinpatterns.md)
- [`rx.testing.js`](doc/libraries/main/rx.testing.md)
- [`rx.time.js`](doc/libraries/main/rx.time.md)
- [`rx.virtualtime.js`](doc/libraries/main/rx.virtualtime.md)
### Lite Libraries:
- [`rx.lite.js`](doc/libraries/lite/rx.lite.md)
- [`rx.lite.extras.js`](doc/libraries/lite/rx.lite.extras.md)
- [`rx.lite.aggregates.js`](doc/libraries/lite/rx.lite.aggregates.md)
- [`rx.lite.async.js`](doc/libraries/lite/rx.lite.async.md)
- [`rx.lite.coincidence.js`](doc/libraries/lite/rx.lite.coincidence.md)
- [`rx.lite.experimental.js`](doc/libraries/lite/rx.lite.experimental.md)
- [`rx.lite.joinpatterns.js`](doc/libraries/lite/rx.lite.joinpatterns.md)
- [`rx.lite.testing.js`](doc/libraries/lite/rx.lite.testing.md)
- [`rx.lite.time.js`](doc/libraries/lite/rx.lite.time.md)
- [`rx.lite.virtualtime.js`](doc/libraries/lite/rx.lite.virtualtime.md)
### Core Libraries:
- [`rx.core.js`](doc/libraries/core/rx.core.md)
- [`rx.core.binding.js`](doc/libraries/core/rx.core.binding.md)
- [`rx.core.testing.js`](doc/libraries/core/rx.core.testing.md)
## Why RxJS? ##
One question you may ask yourself is why RxJS? What about Promises? Promises are good for solving asynchronous operations such as querying a service with an XMLHttpRequest, where the expected behavior is one value and then completion. Reactive Extensions for JavaScript unify both the world of Promises, callbacks as well as evented data such as DOM Input, Web Workers, and Web Sockets. Unifying these concepts enables rich composition.
To give you an idea about rich composition, we can create an autocompletion service which takes user input from a text input and then throttles queries to a service (to avoid flooding the service with calls for every key stroke).
First, we'll reference the JavaScript files, including jQuery, although RxJS has no dependencies on jQuery...
```html
```
Next, we'll get the user input from an input, listening to the keyup event by using the `Rx.Observable.fromEvent` method. This will either use the event binding from [jQuery](http://jquery.com), [Zepto](http://zeptojs.com/), [AngularJS](https://angularjs.org/), [Backbone.js](http://backbonejs.org/) and [Ember.js](http://emberjs.com/) if available, and if not, falls back to the native event binding. This gives you consistent ways of thinking of events depending on your framework, so there are no surprises.
```js
const $input = $('#input');
const $results = $('#results');
/* Only get the value from each key up */
var keyups = Rx.Observable.fromEvent($input, 'keyup')
.pluck('target', 'value')
.filter(text => text.length > 2 );
/* Now debounce the input for 500ms */
var debounced = keyups
.debounce(500 /* ms */);
/* Now get only distinct values, so we eliminate the arrows and other control characters */
var distinct = debounced
.distinctUntilChanged();
```
Now, let's query Wikipedia! In RxJS, we can instantly bind to any [Promises A+](https://github.com/promises-aplus/promises-spec) implementation through the `Rx.Observable.fromPromise` method. Or, directly return it and RxJS will wrap it for you.
```js
let searchWikipedia = (term) => {
return $.ajax({
url: 'https://en.wikipedia.org/w/api.php',
dataType: 'jsonp',
data: {
action: 'opensearch',
format: 'json',
search: term
}
}).promise();
}
```
Once that is created, we can tie together the distinct throttled input and query the service. In this case, we'll call `flatMapLatest` to get the value and ensure we're not introducing any out of order sequence calls.
```js
const suggestions = distinct
.flatMapLatest(searchWikipedia);
```
Finally, we call the `subscribe` method on our observable sequence to start pulling data.
```js
suggestions.subscribe(
data => {
$results
.empty()
.append($.map(data[1], value => $('
'))
.text(`Error: ${error}`);
});
```
And there you have it!
## Dive In! ##
Please check out:
- [Our Code of Conduct](https://github.com/Reactive-Extensions/RxJS/tree/master/code-of-conduct.md)
- [The full documentation](https://github.com/Reactive-Extensions/RxJS/tree/master/doc)
- [Our many great examples](https://github.com/Reactive-Extensions/RxJS/tree/master/examples)
- [Our design guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/designguidelines)
- [Our contribution guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/contributing.md)
- [Our complete Unit Tests](https://github.com/Reactive-Extensions/RxJS/tree/master/tests)
- [Our recipes](https://github.com/Reactive-Extensions/RxJS/wiki/Recipes)
## Resources
- Contact us
- [Twitter @ReactiveX](https://twitter.com/ReactiveX)
- [Gitter.im](https://gitter.im/Reactive-Extensions/RxJS)
- [StackOverflow rxjs](http://stackoverflow.com/questions/tagged/rxjs)
- Tutorials
- [The introduction to Reactive Programming you've been missing](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754)
- [2 minute introduction to Rx](https://medium.com/@andrestaltz/2-minute-introduction-to-rx-24c8ca793877)
- [Learn RxJS - @jhusain](https://github.com/jhusain/learnrx)
- [RxJS Koans](https://github.com/Reactive-Extensions/RxJSKoans)
- [RxJS Workshop from BuildStuff 2014](https://github.com/Reactive-Extensions/BuildStuffWorkshop)
- [Rx Workshop](http://rxworkshop.codeplex.com/)
- [Reactive Programming and MVC](http://aaronstacy.com/writings/reactive-programming-and-mvc/)
- [RxJS lessons - egghead.io](https://egghead.io/technologies/rx)
- [RxJS Training - @andrestaltz](https://github.com/staltz/rxjs-training)
- Reference Material
- [Rx Marbles](http://rxmarbles.com/)
- [RxJS GitBook](http://xgrommx.github.io/rx-book/)
- [Intro to Rx](http://introtorx.com/)
- [101 Rx Samples Wiki](http://rxwiki.wikidot.com/101samples)
- [RxJS Design Guidelines](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/designguidelines)
- [Visualizing Reactive Streams](http://jaredforsyth.com/2015/03/06/visualizing-reactive-streams-hot-and-cold/)
- [Your Mouse is a Database](http://queue.acm.org/detail.cfm?id=2169076)
- Essential tools
- [RxVision](http://jaredforsyth.com/rxvision/)
- [Percussion](https://github.com/grisendo/Percussion)
- Books
- [RxJS in Action](https://www.manning.com/books/rxjs-in-action)
- [RxJS](http://xgrommx.github.io/rx-book/)
- [Intro to Rx](http://www.amazon.com/Introduction-to-Rx-ebook/dp/B008GM3YPM/)
- [Programming Reactive Extensions and LINQ](http://www.amazon.com/Programming-Reactive-Extensions-Jesse-Liberty/dp/1430237473/)
- [Reactive Programming with RxJS](https://pragprog.com/book/smreactjs/reactive-programming-with-rxjs)
- [Community Examples](examples/community.md)
- [Presentations](examples/presentations.md)
- [Videos and Podcasts](examples/videos.md)
## Getting Started
There are a number of ways to get started with RxJS. The files are available on [cdnjs](http://cdnjs.com/libraries/rxjs/) and [jsDelivr](http://www.jsdelivr.com/#!rxjs).
### Download the Source
```bash
git clone https://github.com/Reactive-Extensions/rxjs.git
cd ./rxjs
```
### Installing with [NPM](https://www.npmjs.com/)
```bash`
$ npm install rx
$ npm install -g rx
```
### Using with Node.js and Ringo.js
```js
var Rx = require('rx');
```
### Installing with [Bower](http://bower.io/)
```bash
$ bower install rxjs
```
### Installing with [Jam](http://jamjs.org/)
```bash
$ jam install rx
```
### Installing All of RxJS via [NuGet](http://www.nuget.org/)
```bash
$ Install-Package RxJS-All
```
### Install individual packages via [NuGet](http://www.nuget.org/):
Install-Package RxJS-All
Install-Package RxJS-Lite
Install-Package RxJS-Main
Install-Package RxJS-Aggregates
Install-Package RxJS-Async
Install-Package RxJS-BackPressure
Install-Package RxJS-Binding
Install-Package RxJS-Coincidence
Install-Package RxJS-Experimental
Install-Package RxJS-JoinPatterns
Install-Package RxJS-Testing
Install-Package RxJS-Time
### In a Browser:
```html
```
### Along with a number of our extras for RxJS:
```html
```
### Using RxJS with an AMD loader such as Require.js
```js
require({
'paths': {
'rx': 'path/to/rx-lite.js'
}
},
['rx'], (Rx) => {
const obs = Rx.Observable.of(42);
obs.forEach(x => console.log(x));
});
```
## What about my libraries? ##
The Reactive Extensions for JavaScript have no external dependencies on any library, so they'll work well with just about any library. We provide bridges and support for various libraries including:
- [Node.js](https://www.npmjs.com/package/rx-node)
- [React](http://facebook.github.io/react/)
- [Rx-React](https://github.com/fdecampredon/rx-react)
- [RxReact](https://github.com/AlexMost/RxReact)
- [cycle-react](https://github.com/pH200/cycle-react)
- [Flux](http://facebook.github.io/flux/)
- [Rx-Flux](https://github.com/fdecampredon/rx-flux)
- [ReactiveFlux](https://github.com/codesuki/reactive-flux)
- [Thundercats.js](https://github.com/ThunderCatsJS/thundercats)
- [Flurx](https://github.com/qwtel/flurx)
- [RR](https://github.com/winsonwq/RR)
- [Ember](http://emberjs.com/)
- [RxEmber](https://github.com/blesh/RxEmber)
- [AngularJS](https://github.com/Reactive-Extensions/rx.angular.js)
- [HTML DOM](https://github.com/Reactive-Extensions/RxJS-DOM)
- [jQuery (1.4+)](https://github.com/Reactive-Extensions/RxJS-jQuery)
- [MooTools](https://github.com/Reactive-Extensions/RxJS-MooTools)
- [Dojo 1.7+](https://github.com/Reactive-Extensions/RxJS-Dojo)
- [ExtJS](https://github.com/Reactive-Extensions/RxJS-ExtJS)
## Compatibility ##
RxJS has been thoroughly tested against all major browsers and supports IE6+, Chrome 4+, FireFox 1+, and Node.js v0.4+.
## Contributing ##
There are lots of ways to contribute to the project, and we appreciate our [contributors](https://github.com/Reactive-Extensions/RxJS/wiki/Contributors). If you wish to contribute, check out our [style guide]((https://github.com/Reactive-Extensions/RxJS/tree/master/doc/contributing)).
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
First-time contributors must sign a [Contribution License Agreement](https://cla.microsoft.com/). If your Pull Request has the label [cla-required](https://github.com/Reactive-Extensions/RxJS/labels/cla-required), this is an indication that you haven't yet signed such an agreement.
## License ##
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Microsoft Open Technologies would like to thank its contributors, a list
of whom are at https://github.com/Reactive-Extensions/RxJS/wiki/Contributors.
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
================================================
FILE: src/core/abstractobserver.js
================================================
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
var AbstractObserver = Rx.internals.AbstractObserver = (function (__super__) {
inherits(AbstractObserver, __super__);
/**
* Creates a new observer in a non-stopped state.
*/
function AbstractObserver() {
this.isStopped = false;
}
// Must be implemented by other observers
AbstractObserver.prototype.next = notImplemented;
AbstractObserver.prototype.error = notImplemented;
AbstractObserver.prototype.completed = notImplemented;
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
AbstractObserver.prototype.onNext = function (value) {
!this.isStopped && this.next(value);
};
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
AbstractObserver.prototype.onError = function (error) {
if (!this.isStopped) {
this.isStopped = true;
this.error(error);
}
};
/**
* Notifies the observer of the end of the sequence.
*/
AbstractObserver.prototype.onCompleted = function () {
if (!this.isStopped) {
this.isStopped = true;
this.completed();
}
};
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
AbstractObserver.prototype.dispose = function () { this.isStopped = true; };
AbstractObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.error(e);
return true;
}
return false;
};
return AbstractObserver;
}(Observer));
================================================
FILE: src/core/anonymousobservable.js
================================================
var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) {
inherits(AnonymousObservable, __super__);
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
__super__.call(this);
}
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
return AnonymousObservable;
}(Observable));
================================================
FILE: src/core/anonymousobserver.js
================================================
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
var AnonymousObserver = Rx.AnonymousObserver = (function (__super__) {
inherits(AnonymousObserver, __super__);
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
function AnonymousObserver(onNext, onError, onCompleted) {
__super__.call(this);
this._onNext = onNext;
this._onError = onError;
this._onCompleted = onCompleted;
}
/**
* Calls the onNext action.
* @param {Any} value Next element in the sequence.
*/
AnonymousObserver.prototype.next = function (value) {
this._onNext(value);
};
/**
* Calls the onError action.
* @param {Any} error The error that has occurred.
*/
AnonymousObserver.prototype.error = function (error) {
this._onError(error);
};
/**
* Calls the onCompleted action.
*/
AnonymousObserver.prototype.completed = function () {
this._onCompleted();
};
return AnonymousObserver;
}(AbstractObserver));
================================================
FILE: src/core/autodetachobserver.js
================================================
var AutoDetachObserver = (function (__super__) {
inherits(AutoDetachObserver, __super__);
function AutoDetachObserver(observer) {
__super__.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
var AutoDetachObserverPrototype = AutoDetachObserver.prototype;
AutoDetachObserverPrototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserverPrototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); };
AutoDetachObserverPrototype.getDisposable = function () { return this.m.getDisposable(); };
AutoDetachObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
this.m.dispose();
};
return AutoDetachObserver;
}(AbstractObserver));
================================================
FILE: src/core/backpressure/controlled.js
================================================
var ControlledObservable = (function (__super__) {
inherits(ControlledObservable, __super__);
function ControlledObservable (source, enableQueue, scheduler) {
__super__.call(this);
this.subject = new ControlledSubject(enableQueue, scheduler);
this.source = source.multicast(this.subject).refCount();
}
ControlledObservable.prototype._subscribe = function (o) {
return this.source.subscribe(o);
};
ControlledObservable.prototype.request = function (numberOfItems) {
return this.subject.request(numberOfItems == null ? -1 : numberOfItems);
};
return ControlledObservable;
}(Observable));
var ControlledSubject = (function (__super__) {
inherits(ControlledSubject, __super__);
function ControlledSubject(enableQueue, scheduler) {
enableQueue == null && (enableQueue = true);
__super__.call(this);
this.subject = new Subject();
this.enableQueue = enableQueue;
this.queue = enableQueue ? [] : null;
this.requestedCount = 0;
this.requestedDisposable = null;
this.error = null;
this.hasFailed = false;
this.hasCompleted = false;
this.scheduler = scheduler || currentThreadScheduler;
}
addProperties(ControlledSubject.prototype, Observer, {
_subscribe: function (o) {
return this.subject.subscribe(o);
},
onCompleted: function () {
this.hasCompleted = true;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onCompleted();
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnCompleted());
}
},
onError: function (error) {
this.hasFailed = true;
this.error = error;
if (!this.enableQueue || this.queue.length === 0) {
this.subject.onError(error);
this.disposeCurrentRequest();
} else {
this.queue.push(Notification.createOnError(error));
}
},
onNext: function (value) {
if (this.requestedCount <= 0) {
this.enableQueue && this.queue.push(Notification.createOnNext(value));
} else {
(this.requestedCount-- === 0) && this.disposeCurrentRequest();
this.subject.onNext(value);
}
},
_processRequest: function (numberOfItems) {
if (this.enableQueue) {
while (this.queue.length > 0 && (numberOfItems > 0 || this.queue[0].kind !== 'N')) {
var first = this.queue.shift();
first.accept(this.subject);
if (first.kind === 'N') {
numberOfItems--;
} else {
this.disposeCurrentRequest();
this.queue = [];
}
}
}
return numberOfItems;
},
request: function (number) {
this.disposeCurrentRequest();
var self = this;
this.requestedDisposable = this.scheduler.schedule(number,
function(s, i) {
var remaining = self._processRequest(i);
var stopped = self.hasCompleted || self.hasFailed;
if (!stopped && remaining > 0) {
self.requestedCount = remaining;
return disposableCreate(function () {
self.requestedCount = 0;
});
// Scheduled item is still in progress. Return a new
// disposable to allow the request to be interrupted
// via dispose.
}
});
return this.requestedDisposable;
},
disposeCurrentRequest: function () {
if (this.requestedDisposable) {
this.requestedDisposable.dispose();
this.requestedDisposable = null;
}
}
});
return ControlledSubject;
}(Observable));
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
observableProto.controlled = function (enableQueue, scheduler) {
if (enableQueue && isScheduler(enableQueue)) {
scheduler = enableQueue;
enableQueue = true;
}
if (enableQueue == null) { enableQueue = true; }
return new ControlledObservable(this, enableQueue, scheduler);
};
================================================
FILE: src/core/backpressure/pausable.js
================================================
var PausableObservable = (function (__super__) {
inherits(PausableObservable, __super__);
function PausableObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableObservable.prototype._subscribe = function (o) {
var conn = this.source.publish(),
subscription = conn.subscribe(o),
connection = disposableEmpty;
var pausable = this.pauser.startWith(!this.paused).distinctUntilChanged().subscribe(function (b) {
if (b) {
connection = conn.connect();
} else {
connection.dispose();
connection = disposableEmpty;
}
});
return new NAryDisposable([subscription, connection, pausable]);
};
PausableObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausable = function (pauser) {
return new PausableObservable(this, pauser);
};
================================================
FILE: src/core/backpressure/pausablebuffered.js
================================================
function combineLatestSource(source, subject, resultSelector) {
return new AnonymousObservable(function (o) {
var hasValue = [false, false],
hasValueAll = false,
isDone = false,
values = new Array(2),
err;
function next(x, i) {
values[i] = x;
hasValue[i] = true;
if (hasValueAll || (hasValueAll = hasValue.every(identity))) {
if (err) { return o.onError(err); }
var res = tryCatch(resultSelector).apply(null, values);
if (res === errorObj) { return o.onError(res.e); }
o.onNext(res);
}
isDone && values[1] && o.onCompleted();
}
return new BinaryDisposable(
source.subscribe(
function (x) {
next(x, 0);
},
function (e) {
if (values[1]) {
o.onError(e);
} else {
err = e;
}
},
function () {
isDone = true;
values[1] && o.onCompleted();
}),
subject.subscribe(
function (x) {
next(x, 1);
},
function (e) { o.onError(e); },
function () {
isDone = true;
next(true, 1);
})
);
}, source);
}
var PausableBufferedObservable = (function (__super__) {
inherits(PausableBufferedObservable, __super__);
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = this.controller.merge(pauser);
} else {
this.pauser = this.controller;
}
__super__.call(this);
}
PausableBufferedObservable.prototype._subscribe = function (o) {
var q = [], previousShouldFire;
function drainQueue() { while (q.length > 0) { o.onNext(q.shift()); } }
var subscription =
combineLatestSource(
this.source,
this.pauser.startWith(!this.paused).distinctUntilChanged(),
function (data, shouldFire) {
return { data: data, shouldFire: shouldFire };
})
.subscribe(
function (results) {
if (previousShouldFire !== undefined && results.shouldFire !== previousShouldFire) {
previousShouldFire = results.shouldFire;
// change in shouldFire
if (results.shouldFire) { drainQueue(); }
} else {
previousShouldFire = results.shouldFire;
// new data
if (results.shouldFire) {
o.onNext(results.data);
} else {
q.push(results.data);
}
}
},
function (err) {
drainQueue();
o.onError(err);
},
function () {
drainQueue();
o.onCompleted();
}
);
return subscription;
};
PausableBufferedObservable.prototype.pause = function () {
this.paused = true;
this.controller.onNext(false);
};
PausableBufferedObservable.prototype.resume = function () {
this.paused = false;
this.controller.onNext(true);
};
return PausableBufferedObservable;
}(Observable));
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
observableProto.pausableBuffered = function (pauser) {
return new PausableBufferedObservable(this, pauser);
};
================================================
FILE: src/core/backpressure/pauser.js
================================================
/**
* Used to pause and resume streams.
*/
Rx.Pauser = (function (__super__) {
inherits(Pauser, __super__);
function Pauser() {
__super__.call(this);
}
/**
* Pauses the underlying sequence.
*/
Pauser.prototype.pause = function () { this.onNext(false); };
/**
* Resumes the underlying sequence.
*/
Pauser.prototype.resume = function () { this.onNext(true); };
return Pauser;
}(Subject));
================================================
FILE: src/core/backpressure/stopandwait.js
================================================
var StopAndWaitObservable = (function (__super__) {
inherits(StopAndWaitObservable, __super__);
function StopAndWaitObservable (source) {
__super__.call(this);
this.source = source;
}
function scheduleMethod(s, self) {
return self.source.request(1);
}
StopAndWaitObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new StopAndWaitObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var StopAndWaitObserver = (function (__sub__) {
inherits(StopAndWaitObserver, __sub__);
function StopAndWaitObserver (observer, observable, cancel) {
__sub__.call(this);
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.scheduleDisposable = null;
}
StopAndWaitObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
StopAndWaitObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(1);
}
StopAndWaitObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod);
};
StopAndWaitObserver.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return StopAndWaitObserver;
}(AbstractObserver));
return StopAndWaitObservable;
}(Observable));
/**
* Attaches a stop and wait observable to the current observable.
* @returns {Observable} A stop and wait observable.
*/
ControlledObservable.prototype.stopAndWait = function () {
return new StopAndWaitObservable(this);
};
================================================
FILE: src/core/backpressure/windowed.js
================================================
var WindowedObservable = (function (__super__) {
inherits(WindowedObservable, __super__);
function WindowedObservable(source, windowSize) {
__super__.call(this);
this.source = source;
this.windowSize = windowSize;
}
function scheduleMethod(s, self) {
return self.source.request(self.windowSize);
}
WindowedObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new WindowedObserver(o, this, this.subscription));
return new BinaryDisposable(
this.subscription,
defaultScheduler.schedule(this, scheduleMethod)
);
};
var WindowedObserver = (function (__sub__) {
inherits(WindowedObserver, __sub__);
function WindowedObserver(observer, observable, cancel) {
this.observer = observer;
this.observable = observable;
this.cancel = cancel;
this.received = 0;
this.scheduleDisposable = null;
__sub__.call(this);
}
WindowedObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
WindowedObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(self.observable.windowSize);
}
WindowedObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.received = ++this.received % this.observable.windowSize;
this.received === 0 && (this.scheduleDisposable = defaultScheduler.schedule(this, innerScheduleMethod));
};
WindowedObserver.prototype.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
__sub__.prototype.dispose.call(this);
};
return WindowedObserver;
}(AbstractObserver));
return WindowedObservable;
}(Observable));
/**
* Creates a sliding windowed observable based upon the window size.
* @param {Number} windowSize The number of items in the window
* @returns {Observable} A windowed observable based upon the window size.
*/
ControlledObservable.prototype.windowed = function (windowSize) {
return new WindowedObservable(this, windowSize);
};
================================================
FILE: src/core/checkedobserver.js
================================================
var CheckedObserver = (function (__super__) {
inherits(CheckedObserver, __super__);
function CheckedObserver(observer) {
__super__.call(this);
this._observer = observer;
this._state = 0; // 0 - idle, 1 - busy, 2 - done
}
var CheckedObserverPrototype = CheckedObserver.prototype;
CheckedObserverPrototype.onNext = function (value) {
this.checkAccess();
var res = tryCatch(this._observer.onNext).call(this._observer, value);
this._state = 0;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onError = function (err) {
this.checkAccess();
var res = tryCatch(this._observer.onError).call(this._observer, err);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.onCompleted = function () {
this.checkAccess();
var res = tryCatch(this._observer.onCompleted).call(this._observer);
this._state = 2;
res === errorObj && thrower(res.e);
};
CheckedObserverPrototype.checkAccess = function () {
if (this._state === 1) { throw new Error('Re-entrancy detected'); }
if (this._state === 2) { throw new Error('Observer completed'); }
if (this._state === 0) { this._state = 1; }
};
return CheckedObserver;
}(Observer));
================================================
FILE: src/core/concurrency/catchscheduler.js
================================================
var CatchScheduler = (function (__super__) {
inherits(CatchScheduler, __super__);
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
__super__.call(this);
}
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () { return this._scheduler.now(); };
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) { thrower(res.e); }
return disposableEmpty;
}
return disposableFixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this, failed = false, d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) { return null; }
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) { thrower(res.e); }
d.dispose();
return null;
}
return res;
}));
return d;
};
return CatchScheduler;
}(Scheduler));
================================================
FILE: src/core/concurrency/currentthreadscheduler.js
================================================
/**
* Gets a scheduler that schedules work as soon as possible on the current thread.
*/
var CurrentThreadScheduler = (function (__super__) {
var queue;
function runTrampoline () {
while (queue.length > 0) {
var item = queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
inherits(CurrentThreadScheduler, __super__);
function CurrentThreadScheduler() {
__super__.call(this);
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!queue) {
queue = new PriorityQueue(4);
queue.enqueue(si);
var result = tryCatch(runTrampoline)();
queue = null;
if (result === errorObj) { thrower(result.e); }
} else {
queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () { return !queue; };
return CurrentThreadScheduler;
}(Scheduler));
var currentThreadScheduler = Scheduler.currentThread = new CurrentThreadScheduler();
================================================
FILE: src/core/concurrency/defaultscheduler.js
================================================
var scheduleMethod, clearMethod;
var localTimer = (function () {
var localSetTimeout, localClearTimeout = noop;
if (!!root.setTimeout) {
localSetTimeout = root.setTimeout;
localClearTimeout = root.clearTimeout;
} else if (!!root.WScript) {
localSetTimeout = function (fn, time) {
root.WScript.Sleep(time);
fn();
};
} else {
throw new NotSupportedError();
}
return {
setTimeout: localSetTimeout,
clearTimeout: localClearTimeout
};
}());
var localSetTimeout = localTimer.setTimeout,
localClearTimeout = localTimer.clearTimeout;
(function () {
var nextHandle = 1, tasksByHandle = {}, currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
localSetTimeout(function () { runTask(handle); }, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) { thrower(result.e); }
}
}
}
var reNative = new RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' &&
!reNative.test(setImmediate) && setImmediate;
function postMessageSupported () {
// Ensure not in a worker
if (!root.postMessage || root.importScripts) { return false; }
var isAsync = false, oldHandler = root.onmessage;
// Test for async
root.onmessage = function () { isAsync = true; };
root.postMessage('', '*');
root.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () { runTask(id); });
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () { runTask(id); });
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
root.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
root.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!root.MessageChannel) {
var channel = new root.MessageChannel();
channel.port1.onmessage = function (e) { runTask(e.data); };
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = root.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
root.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
localSetTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
}());
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
var DefaultScheduler = (function (__super__) {
inherits(DefaultScheduler, __super__);
function DefaultScheduler() {
__super__.call(this);
}
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
clearMethod(this._id);
}
};
function LocalClearDisposable(id) {
this._id = id;
this.isDisposed = false;
}
LocalClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
localClearTimeout(this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) { return this.schedule(state, action); }
var disposable = new SingleAssignmentDisposable(),
id = localSetTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new LocalClearDisposable(id));
};
function scheduleLongRunning(state, action, disposable) {
return function () { action(state, disposable); };
}
DefaultScheduler.prototype.scheduleLongRunning = function (state, action) {
var disposable = disposableCreate(noop);
scheduleMethod(scheduleLongRunning(state, action, disposable));
return disposable;
};
return DefaultScheduler;
}(Scheduler));
var defaultScheduler = Scheduler['default'] = Scheduler.async = new DefaultScheduler();
================================================
FILE: src/core/concurrency/historicalscheduler.js
================================================
/** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */
Rx.HistoricalScheduler = (function (__super__) {
inherits(HistoricalScheduler, __super__);
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function HistoricalScheduler(initialClock, comparer) {
var clock = initialClock == null ? 0 : initialClock;
var cmp = comparer || defaultSubComparer;
__super__.call(this, clock, cmp);
}
var HistoricalSchedulerProto = HistoricalScheduler.prototype;
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
HistoricalSchedulerProto.add = function (absolute, relative) {
return absolute + relative;
};
HistoricalSchedulerProto.toAbsoluteTime = function (absolute) {
return new Date(absolute).getTime();
};
/**
* Converts the TimeSpan value to a relative virtual time value.
* @memberOf HistoricalScheduler
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
HistoricalSchedulerProto.toRelativeTime = function (timeSpan) {
return timeSpan;
};
return HistoricalScheduler;
}(Rx.VirtualTimeScheduler));
================================================
FILE: src/core/concurrency/immediatescheduler.js
================================================
/** Gets a scheduler that schedules work immediately on the current thread. */
var ImmediateScheduler = (function (__super__) {
inherits(ImmediateScheduler, __super__);
function ImmediateScheduler() {
__super__.call(this);
}
ImmediateScheduler.prototype.schedule = function (state, action) {
return disposableFixup(action(this, state));
};
return ImmediateScheduler;
}(Scheduler));
var immediateScheduler = Scheduler.immediate = new ImmediateScheduler();
================================================
FILE: src/core/concurrency/scheduleditem.js
================================================
var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || defaultSubComparer;
this.disposable = new SingleAssignmentDisposable();
};
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return disposableFixup(this.action(this.scheduler, this.state));
};
================================================
FILE: src/core/concurrency/scheduleperiodicrecursive.js
================================================
var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () {
function createTick(self) {
return function tick(command, recurse) {
recurse(0, self._period);
var state = tryCatch(self._action)(self._state);
if (state === errorObj) {
self._cancel.dispose();
thrower(state.e);
}
self._state = state;
};
}
function SchedulePeriodicRecursive(scheduler, state, period, action) {
this._scheduler = scheduler;
this._state = state;
this._period = period;
this._action = action;
}
SchedulePeriodicRecursive.prototype.start = function () {
var d = new SingleAssignmentDisposable();
this._cancel = d;
d.setDisposable(this._scheduler.scheduleRecursiveFuture(0, this._period, createTick(this)));
return d;
};
return SchedulePeriodicRecursive;
}());
================================================
FILE: src/core/concurrency/scheduler.js
================================================
/** Provides a set of static properties to access commonly used schedulers. */
var Scheduler = Rx.Scheduler = (function () {
function Scheduler() { }
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
var schedulerProto = Scheduler.prototype;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.schedule = function (state, action) {
throw new NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) { return this.schedule(state, action); }
return this._scheduleFuture(state, dt, action);
};
schedulerProto._scheduleFuture = function (state, dueTime, action) {
throw new NotImplementedError();
};
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
return Scheduler;
}());
var normalizeTime = Scheduler.normalize, isScheduler = Scheduler.isScheduler;
================================================
FILE: src/core/concurrency/scheduler.periodic.js
================================================
(function (schedulerProto) {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulerProto.schedulePeriodic = function(state, period, action) {
if (typeof root.setInterval === 'undefined') { throw new NotSupportedError(); }
period = normalizeTime(period);
var s = state, id = root.setInterval(function () { s = action(s); }, period);
return disposableCreate(function () { root.clearInterval(id); });
};
}(Scheduler.prototype));
================================================
FILE: src/core/concurrency/scheduler.recursive.js
================================================
(function (schedulerProto) {
function invokeRecImmediate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false, isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0], action = pair[1], group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false, isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return disposableEmpty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedulerProto.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
}(Scheduler.prototype));
================================================
FILE: src/core/concurrency/scheduler.wrappers.js
================================================
(function (schedulerProto) {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
schedulerProto.catchError = schedulerProto['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
}(Scheduler.prototype));
================================================
FILE: src/core/concurrency/virtualtimescheduler.js
================================================
/** Provides a set of extension methods for virtual time scheduling. */
var VirtualTimeScheduler = Rx.VirtualTimeScheduler = (function (__super__) {
inherits(VirtualTimeScheduler, __super__);
/**
* Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer.
*
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
function VirtualTimeScheduler(initialClock, comparer) {
this.clock = initialClock;
this.comparer = comparer;
this.isEnabled = false;
this.queue = new PriorityQueue(1024);
__super__.call(this);
}
var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype;
VirtualTimeSchedulerPrototype.now = function () {
return this.toAbsoluteTime(this.clock);
};
VirtualTimeSchedulerPrototype.schedule = function (state, action) {
return this.scheduleAbsolute(state, this.clock, action);
};
VirtualTimeSchedulerPrototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime instanceof Date ?
this.toRelativeTime(dueTime - this.now()) :
this.toRelativeTime(dueTime);
return this.scheduleRelative(state, dt, action);
};
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
VirtualTimeSchedulerPrototype.add = notImplemented;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
VirtualTimeSchedulerPrototype.toAbsoluteTime = notImplemented;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
VirtualTimeSchedulerPrototype.toRelativeTime = notImplemented;
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
VirtualTimeSchedulerPrototype.schedulePeriodic = function (state, period, action) {
var s = new SchedulePeriodicRecursive(this, state, period, action);
return s.start();
};
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleRelative = function (state, dueTime, action) {
var runAt = this.add(this.clock, dueTime);
return this.scheduleAbsolute(state, runAt, action);
};
/**
* Starts the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.start = function () {
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
}
};
/**
* Stops the virtual time scheduler.
*/
VirtualTimeSchedulerPrototype.stop = function () {
this.isEnabled = false;
};
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
VirtualTimeSchedulerPrototype.advanceTo = function (time) {
var dueToClock = this.comparer(this.clock, time);
if (this.comparer(this.clock, time) > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
if (!this.isEnabled) {
this.isEnabled = true;
do {
var next = this.getNext();
if (next !== null && this.comparer(next.dueTime, time) <= 0) {
this.comparer(next.dueTime, this.clock) > 0 && (this.clock = next.dueTime);
next.invoke();
} else {
this.isEnabled = false;
}
} while (this.isEnabled);
this.clock = time;
}
};
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.advanceBy = function (time) {
var dt = this.add(this.clock, time),
dueToClock = this.comparer(this.clock, dt);
if (dueToClock > 0) { throw new ArgumentOutOfRangeError(); }
if (dueToClock === 0) { return; }
this.advanceTo(dt);
};
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
VirtualTimeSchedulerPrototype.sleep = function (time) {
var dt = this.add(this.clock, time);
if (this.comparer(this.clock, dt) >= 0) { throw new ArgumentOutOfRangeError(); }
this.clock = dt;
};
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
VirtualTimeSchedulerPrototype.getNext = function () {
while (this.queue.length > 0) {
var next = this.queue.peek();
if (next.isCancelled()) {
this.queue.dequeue();
} else {
return next;
}
}
return null;
};
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
VirtualTimeSchedulerPrototype.scheduleAbsolute = function (state, dueTime, action) {
var self = this;
function run(scheduler, state1) {
self.queue.remove(si);
return action(scheduler, state1);
}
var si = new ScheduledItem(this, state, run, dueTime, this.comparer);
this.queue.enqueue(si);
return si.disposable;
};
return VirtualTimeScheduler;
}(Scheduler));
================================================
FILE: src/core/disposables/binarydisposable.js
================================================
var BinaryDisposable = Rx.BinaryDisposable = function (first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
};
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
var NAryDisposable = Rx.NAryDisposable = function (disposables) {
this._disposables = disposables;
this.isDisposed = false;
};
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
================================================
FILE: src/core/disposables/booleandisposable.js
================================================
// Single assignment
var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this.current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this.current) { throw new Error('Disposable has already been assigned'); }
var shouldDispose = this.isDisposed;
!shouldDispose && (this.current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
old && old.dispose();
}
};
// Multiple assignment disposable
var SerialDisposable = Rx.SerialDisposable = function () {
this.isDisposed = false;
this.current = null;
};
SerialDisposable.prototype.getDisposable = function () {
return this.current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this.current;
this.current = value;
}
old && old.dispose();
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this.current;
this.current = null;
}
old && old.dispose();
};
================================================
FILE: src/core/disposables/compositedisposable.js
================================================
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
var CompositeDisposable = Rx.CompositeDisposable = function () {
var args = [], i, len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
len = arguments.length;
args = new Array(len);
for(i = 0; i < len; i++) { args[i] = arguments[i]; }
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
};
var CompositeDisposablePrototype = CompositeDisposable.prototype;
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposablePrototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposablePrototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposablePrototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length, currentDisposables = new Array(len);
for(var i = 0; i < len; i++) { currentDisposables[i] = this.disposables[i]; }
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
================================================
FILE: src/core/disposables/disposable.js
================================================
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
var Disposable = Rx.Disposable = function (action) {
this.isDisposed = false;
this.action = action || noop;
};
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
var disposableCreate = Disposable.create = function (action) { return new Disposable(action); };
/**
* Gets the disposable that does nothing when disposed.
*/
var disposableEmpty = Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
var isDisposable = Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
var checkDisposed = Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) { throw new ObjectDisposedError(); }
};
var disposableFixup = Disposable._fixup = function (result) {
return isDisposable(result) ? result : disposableEmpty;
};
================================================
FILE: src/core/disposables/refcountdisposable.js
================================================
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
var RefCountDisposable = Rx.RefCountDisposable = (function () {
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? disposableEmpty : new InnerDisposable(this);
};
return RefCountDisposable;
})();
================================================
FILE: src/core/disposables/scheduleddisposable.js
================================================
function ScheduledDisposable(scheduler, disposable) {
this.scheduler = scheduler;
this.disposable = disposable;
this.isDisposed = false;
}
function scheduleItem(s, self) {
if (!self.isDisposed) {
self.isDisposed = true;
self.disposable.dispose();
}
}
ScheduledDisposable.prototype.dispose = function () {
this.scheduler.schedule(this, scheduleItem);
};
================================================
FILE: src/core/enumerable.js
================================================
var Enumerable = Rx.internals.Enumerable = function () { };
function IsDisposedDisposable(state) {
this._s = state;
this.isDisposed = false;
}
IsDisposedDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.isDisposed = true;
}
};
var ConcatEnumerableObservable = (function(__super__) {
inherits(ConcatEnumerableObservable, __super__);
function ConcatEnumerableObservable(sources) {
this.sources = sources;
__super__.call(this);
}
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
ConcatEnumerableObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.o.onError(e); };
InnerObserver.prototype.completed = function () { this._recurse(this._state); };
return ConcatEnumerableObservable;
}(ObservableBase));
Enumerable.prototype.concat = function () {
return new ConcatEnumerableObservable(this);
};
var CatchErrorObservable = (function(__super__) {
function CatchErrorObservable(sources) {
this.sources = sources;
__super__.call(this);
}
inherits(CatchErrorObservable, __super__);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = tryCatch(state.e.next).call(state.e);
if (currentItem === errorObj) { return state.o.onError(currentItem.e); }
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new InnerObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = currentThreadScheduler.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
function InnerObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
InnerObserver.prototype.completed = function () { this._state.o.onCompleted(); };
return CatchErrorObservable;
}(ObservableBase));
Enumerable.prototype.catchError = function () {
return new CatchErrorObservable(this);
};
var RepeatEnumerable = (function (__super__) {
inherits(RepeatEnumerable, __super__);
function RepeatEnumerable(v, c) {
this.v = v;
this.c = c == null ? -1 : c;
}
RepeatEnumerable.prototype[$iterator$] = function () {
return new RepeatEnumerator(this);
};
function RepeatEnumerator(p) {
this.v = p.v;
this.l = p.c;
}
RepeatEnumerator.prototype.next = function () {
if (this.l === 0) { return doneEnumerator; }
if (this.l > 0) { this.l--; }
return { done: false, value: this.v };
};
return RepeatEnumerable;
}(Enumerable));
var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) {
return new RepeatEnumerable(value, repeatCount);
};
var OfEnumerable = (function(__super__) {
inherits(OfEnumerable, __super__);
function OfEnumerable(s, fn, thisArg) {
this.s = s;
this.fn = fn ? bindCallback(fn, thisArg, 3) : null;
}
OfEnumerable.prototype[$iterator$] = function () {
return new OfEnumerator(this);
};
function OfEnumerator(p) {
this.i = -1;
this.s = p.s;
this.l = this.s.length;
this.fn = p.fn;
}
OfEnumerator.prototype.next = function () {
return ++this.i < this.l ?
{ done: false, value: !this.fn ? this.s[this.i] : this.fn(this.s[this.i], this.i, this.s) } :
doneEnumerator;
};
return OfEnumerable;
}(Enumerable));
var enumerableOf = Enumerable.of = function (source, selector, thisArg) {
return new OfEnumerable(source, selector, thisArg);
};
================================================
FILE: src/core/expressions/ExpressionTrees.csproj
================================================
Debug{9286B3D5-AAB5-41FB-B205-ED0ACADBDB98}{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}Librarybinv4.6fulltrue1.4trueweb.configweb.config12.0ExpressionTreesTrueTrue18636/http://localhost:18636/FalseFalseFalsefalsetruetruefalse
================================================
FILE: src/core/expressions/ExpressionTrees.csproj.user
================================================
CurrentPageTrueFalseFalseFalseTrueTrue
================================================
FILE: src/core/expressions/ExpressionTrees.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22823.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionTrees", "ExpressionTrees.csproj", "{9286B3D5-AAB5-41FB-B205-ED0ACADBDB98}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9286B3D5-AAB5-41FB-B205-ED0ACADBDB98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9286B3D5-AAB5-41FB-B205-ED0ACADBDB98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9286B3D5-AAB5-41FB-B205-ED0ACADBDB98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9286B3D5-AAB5-41FB-B205-ED0ACADBDB98}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
================================================
FILE: src/core/expressions/app.css
================================================
body {
font-family: 'Segoe UI', sans-serif;
}
span {
font-style: italic;
}
================================================
FILE: src/core/expressions/app.js
================================================
///
var Tests = (function () {
function Tests(element) {
this.element = element;
}
Tests.prototype.start = function () {
var e = Expression.add(Expression.constant(1), Expression.constant(2));
var l = Expression.lambda(e);
var c = l.compileToFunction();
var f = l.compile();
var b = l.toBonsai();
var x = f();
this.element.innerHTML = "Eval(" + l + ") = Eval(" + c + ") = Eval(" + JSON.stringify(b) + ") = " + x;
};
return Tests;
})();
window.onload = function () {
var el = document.getElementById('content');
var tests = new Tests(el);
tests.start();
};
/*
var resources =
{
"my://xs": [1, 2, 3, 4, 5],
"my://ss": ["bar", "foo", "qux"],
"rx://operators/filter": function (xs: any[], f: (any) => boolean) { return xs.filter(f); },
"rx://operators/map": function (xs: any[], f: (any) => any) { return xs.map(f); },
};
var x = Expression.Parameter("x");
var f1 =
Expression.Invoke(
Expression.Parameter("rx://operators/map"),
Expression.Invoke(
Expression.Parameter("rx://operators/filter"),
Expression.Parameter("my://xs"),
Expression.Lambda<(number) => boolean>(
Expression.Equal(
Expression.Modulo(
x,
Expression.Constant(2)
),
Expression.Constant(0)
),
x
)
),
Expression.Lambda<(number) => boolean>(
Expression.Multiply(
x,
x
),
x
)
);
var f2 =
Expression.Invoke(
Expression.Parameter("rx://operators/map"),
Expression.Parameter("my://ss"),
Expression.Lambda<(string) => string>(
Expression.Call(
x,
"substring",
Expression.Constant(1)
),
x
)
);
var binder = new Binder(resources);
var b1 = Expression.Lambda<() => number[]>(binder.Visit(f1));
var c1 = b1.Compile();
var r1 = c1();
alert(r1.join(", "));
var b2 = Expression.Lambda<() => string[]>(binder.Visit(f2));
var c2 = b2.Compile();
var r2 = c2();
alert(r2.join(", "));
*/
//# sourceMappingURL=app.js.map
================================================
FILE: src/core/expressions/app.ts
================================================
///
class Tests {
element: HTMLElement;
constructor(element: HTMLElement) {
this.element = element;
}
start() {
var e = Expression.add(Expression.constant(1), Expression.constant(2));
var l = Expression.lambda<() => number>(e);
var c = l.compileToFunction();
var f = l.compile();
var b = l.toBonsai();
var x = f();
this.element.innerHTML = "Eval(" + l + ") = Eval(" + c + ") = Eval(" + JSON.stringify(b) + ") = " + x;
}
}
window.onload = () => {
var el = document.getElementById('content');
var tests = new Tests(el);
tests.start();
};
/*
var resources =
{
"my://xs": [1, 2, 3, 4, 5],
"my://ss": ["bar", "foo", "qux"],
"rx://operators/filter": function (xs: any[], f: (any) => boolean) { return xs.filter(f); },
"rx://operators/map": function (xs: any[], f: (any) => any) { return xs.map(f); },
};
var x = Expression.Parameter("x");
var f1 =
Expression.Invoke(
Expression.Parameter("rx://operators/map"),
Expression.Invoke(
Expression.Parameter("rx://operators/filter"),
Expression.Parameter("my://xs"),
Expression.Lambda<(number) => boolean>(
Expression.Equal(
Expression.Modulo(
x,
Expression.Constant(2)
),
Expression.Constant(0)
),
x
)
),
Expression.Lambda<(number) => boolean>(
Expression.Multiply(
x,
x
),
x
)
);
var f2 =
Expression.Invoke(
Expression.Parameter("rx://operators/map"),
Expression.Parameter("my://ss"),
Expression.Lambda<(string) => string>(
Expression.Call(
x,
"substring",
Expression.Constant(1)
),
x
)
);
var binder = new Binder(resources);
var b1 = Expression.Lambda<() => number[]>(binder.Visit(f1));
var c1 = b1.Compile();
var r1 = c1();
alert(r1.join(", "));
var b2 = Expression.Lambda<() => string[]>(binder.Visit(f2));
var c2 = b2.Compile();
var r2 = c2();
alert(r2.join(", "));
*/
================================================
FILE: src/core/expressions/compiler.js
================================================
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Expression = (function () {
function Expression(nodeType) {
this.nodeType = nodeType;
}
Expression.prototype.accept = function (visitor) {
throw new Error("not implemented");
};
Expression.prototype.acceptGeneric = function (visitor) {
throw new Error("not implemented");
};
Expression.prototype.toString = function () {
return new PrintVisitor().visit(this);
};
Expression.prototype.toBonsai = function () {
return new BonsaiVisitor().visit(this);
};
Expression.constant = function (value) {
return new ConstantExpression(value);
};
Expression.parameter = function (name) {
return new ParameterExpression(name);
};
Expression.condition = function (test, ifTrue, ifFalse) {
return new ConditionalExpression(test, ifTrue, ifFalse);
};
Expression.add = function (left, right) {
return new BinaryExpression(3 /* Add */, left, right);
};
Expression.subtract = function (left, right) {
return new BinaryExpression(4 /* Subtract */, left, right);
};
Expression.multiply = function (left, right) {
return new BinaryExpression(5 /* Multiply */, left, right);
};
Expression.divide = function (left, right) {
return new BinaryExpression(6 /* Divide */, left, right);
};
Expression.modulo = function (left, right) {
return new BinaryExpression(7 /* Modulo */, left, right);
};
Expression.and = function (left, right) {
return new BinaryExpression(8 /* And */, left, right);
};
Expression.andAlso = function (left, right) {
return new BinaryExpression(10 /* AndAlso */, left, right);
};
Expression.or = function (left, right) {
return new BinaryExpression(9 /* Or */, left, right);
};
Expression.orElse = function (left, right) {
return new BinaryExpression(11 /* OrElse */, left, right);
};
Expression.exclusiveOr = function (left, right) {
return new BinaryExpression(12 /* ExclusiveOr */, left, right);
};
Expression.equal = function (left, right) {
return new BinaryExpression(13 /* Equal */, left, right);
};
Expression.notEqual = function (left, right) {
return new BinaryExpression(14 /* NotEqual */, left, right);
};
Expression.lessThan = function (left, right) {
return new BinaryExpression(15 /* LessThan */, left, right);
};
Expression.lessThanOrEqual = function (left, right) {
return new BinaryExpression(16 /* LessThanOrEqual */, left, right);
};
Expression.greaterThan = function (left, right) {
return new BinaryExpression(17 /* GreaterThan */, left, right);
};
Expression.greaterThanOrEqual = function (left, right) {
return new BinaryExpression(18 /* GreaterThanOrEqual */, left, right);
};
Expression.leftShift = function (left, right) {
return new BinaryExpression(19 /* LeftShift */, left, right);
};
Expression.rightShift = function (left, right) {
return new BinaryExpression(20 /* RightShift */, left, right);
};
Expression.not = function (operand) {
return new UnaryExpression(22 /* Not */, operand);
};
Expression.unaryPlus = function (operand) {
return new UnaryExpression(24 /* UnaryPlus */, operand);
};
Expression.negate = function (operand) {
return new UnaryExpression(23 /* Negate */, operand);
};
Expression.onesComplement = function (operand) {
return new UnaryExpression(25 /* OnesComplement */, operand);
};
Expression.lambda = function (body) {
var parameters = [];
for (var _i = 1; _i < arguments.length; _i++) {
parameters[_i - 1] = arguments[_i];
}
return new LambdaExpression(body, parameters);
};
Expression.invoke = function (expression) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return new InvocationExpression(expression, args);
};
Expression.new = function (typeName) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return new NewExpression(typeName, args);
};
Expression.functionCall = function (obj, methodName) {
var args = [];
for (var _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
return new FunctionCallExpression(obj, methodName, args);
};
Expression.member = function (obj, memberName) {
return new MemberExpression(obj, memberName);
};
Expression.index = function (obj) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return new IndexExpression(obj, args);
};
return Expression;
})();
var ExpressionVisitorGeneric = (function () {
function ExpressionVisitorGeneric() {
}
ExpressionVisitorGeneric.prototype.visit = function (node) {
if (node === null) {
return null;
}
return node.acceptGeneric(this);
};
ExpressionVisitorGeneric.prototype.visitConstant = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitParameter = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitBinary = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitUnary = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitConditional = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitLambda = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitInvoke = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitCall = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitNew = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitMember = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitIndex = function (node) {
throw new Error("not implemented");
};
ExpressionVisitorGeneric.prototype.visitMany = function (nodes) {
var res = new Array(nodes.length);
for (var i = 0; i < nodes.length; i++) {
var oldNode = nodes[i];
var newNode = this.visit(oldNode);
res[i] = newNode;
}
return res;
};
return ExpressionVisitorGeneric;
})();
var ExpressionVisitor = (function () {
function ExpressionVisitor() {
}
ExpressionVisitor.prototype.visit = function (node) {
if (node === null) {
return null;
}
return node.accept(this);
};
ExpressionVisitor.prototype.visitConstant = function (node) {
return node;
};
ExpressionVisitor.prototype.visitParameter = function (node) {
return node;
};
ExpressionVisitor.prototype.visitBinary = function (node) {
return node.update(this.visit(node.left), this.visit(node.right));
};
ExpressionVisitor.prototype.visitUnary = function (node) {
return node.update(this.visit(node.operand));
};
ExpressionVisitor.prototype.visitConditional = function (node) {
return node.update(this.visit(node.test), this.visit(node.ifTrue), this.visit(node.ifFalse));
};
ExpressionVisitor.prototype.visitLambda = function (node) {
return node.update(this.visit(node.body), this.visitMany(node.parameters));
};
ExpressionVisitor.prototype.visitInvoke = function (node) {
return node.update(this.visit(node.expression), this.visitMany(node.args));
};
ExpressionVisitor.prototype.visitCall = function (node) {
return node.update(this.visit(node.obj), this.visitMany(node.args));
};
ExpressionVisitor.prototype.visitNew = function (node) {
return node.update(this.visitMany(node.args));
};
ExpressionVisitor.prototype.visitMember = function (node) {
return node.update(this.visit(node.obj));
};
ExpressionVisitor.prototype.visitIndex = function (node) {
return node.update(this.visit(node.obj), this.visitMany(node.args));
};
ExpressionVisitor.prototype.visitMany = function (nodes) {
var res = new Array(nodes.length);
for (var i = 0; i < nodes.length; i++) {
var oldNode = nodes[i];
var newNode = this.visit(oldNode);
res[i] = newNode;
}
return res;
};
return ExpressionVisitor;
})();
var ConstantExpression = (function (_super) {
__extends(ConstantExpression, _super);
function ConstantExpression(value) {
_super.call(this, 0 /* Constant */);
this._value = value;
}
Object.defineProperty(ConstantExpression.prototype, "value", {
get: function () {
return this._value;
},
enumerable: true,
configurable: true
});
ConstantExpression.prototype.accept = function (visitor) {
return visitor.visitConstant(this);
};
ConstantExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitConstant(this);
};
return ConstantExpression;
})(Expression);
var ParameterExpression = (function (_super) {
__extends(ParameterExpression, _super);
function ParameterExpression(name) {
_super.call(this, 1 /* Parameter */);
this._name = name;
}
Object.defineProperty(ParameterExpression.prototype, "name", {
get: function () {
return this._name;
},
enumerable: true,
configurable: true
});
ParameterExpression.prototype.accept = function (visitor) {
return visitor.visitParameter(this);
};
ParameterExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitParameter(this);
};
return ParameterExpression;
})(Expression);
var UnaryExpression = (function (_super) {
__extends(UnaryExpression, _super);
function UnaryExpression(nodeType, operand) {
_super.call(this, nodeType);
this._operand = operand;
}
Object.defineProperty(UnaryExpression.prototype, "operand", {
get: function () {
return this._operand;
},
enumerable: true,
configurable: true
});
UnaryExpression.prototype.accept = function (visitor) {
return visitor.visitUnary(this);
};
UnaryExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitUnary(this);
};
UnaryExpression.prototype.update = function (operand) {
if (operand !== this._operand) {
return new UnaryExpression(this.nodeType, operand);
}
return this;
};
return UnaryExpression;
})(Expression);
var BinaryExpression = (function (_super) {
__extends(BinaryExpression, _super);
function BinaryExpression(nodeType, left, right) {
_super.call(this, nodeType);
this._left = left;
this._right = right;
}
Object.defineProperty(BinaryExpression.prototype, "left", {
get: function () {
return this._left;
},
enumerable: true,
configurable: true
});
Object.defineProperty(BinaryExpression.prototype, "right", {
get: function () {
return this._right;
},
enumerable: true,
configurable: true
});
BinaryExpression.prototype.accept = function (visitor) {
return visitor.visitBinary(this);
};
BinaryExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitBinary(this);
};
BinaryExpression.prototype.update = function (left, right) {
if (left !== this._left || right !== this._right) {
return new BinaryExpression(this.nodeType, left, right);
}
return this;
};
return BinaryExpression;
})(Expression);
var ConditionalExpression = (function (_super) {
__extends(ConditionalExpression, _super);
function ConditionalExpression(test, ifTrue, ifFalse) {
_super.call(this, 26 /* Condition */);
this._test = test;
this._ifTrue = ifTrue;
this._ifFalse = ifFalse;
}
Object.defineProperty(ConditionalExpression.prototype, "test", {
get: function () {
return this._test;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConditionalExpression.prototype, "ifTrue", {
get: function () {
return this._ifTrue;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ConditionalExpression.prototype, "ifFalse", {
get: function () {
return this._ifTrue;
},
enumerable: true,
configurable: true
});
ConditionalExpression.prototype.accept = function (visitor) {
return visitor.visitConditional(this);
};
ConditionalExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitConditional(this);
};
ConditionalExpression.prototype.update = function (test, ifTrue, ifFalse) {
if (test !== this._test || ifTrue !== this._ifTrue || ifFalse !== this._ifFalse) {
return new ConditionalExpression(test, ifTrue, ifFalse);
}
return this;
};
return ConditionalExpression;
})(Expression);
var LambdaExpression = (function (_super) {
__extends(LambdaExpression, _super);
function LambdaExpression(body, parameters) {
_super.call(this, 2 /* Lambda */);
this._body = body;
this._parameters = parameters;
}
Object.defineProperty(LambdaExpression.prototype, "body", {
get: function () {
return this._body;
},
enumerable: true,
configurable: true
});
Object.defineProperty(LambdaExpression.prototype, "parameters", {
get: function () {
return this._parameters;
},
enumerable: true,
configurable: true
});
LambdaExpression.prototype.accept = function (visitor) {
return visitor.visitLambda(this);
};
LambdaExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitLambda(this);
};
LambdaExpression.prototype.update = function (body, parameters) {
if (body !== this._body || parameters !== this._parameters) {
return new LambdaExpression(body, parameters);
}
return this;
};
LambdaExpression.prototype.compileToFunction = function (debug) {
var comp = new LambdaCompiler();
comp.visit(this);
var code = comp.code;
code = code.replace(/\"/g, "\\\""); // TODO: more escape sequences
code = "new Function(\"return " + code + ";\")";
code = code.replace(/\r?\n|\r/g, "");
if (debug) {
alert(code);
}
return code;
};
LambdaExpression.prototype.compile = function (debug) {
var code = this.compileToFunction(debug);
return eval(code)();
};
return LambdaExpression;
})(Expression);
var InvocationExpression = (function (_super) {
__extends(InvocationExpression, _super);
function InvocationExpression(expression, args) {
_super.call(this, 21 /* Invoke */);
this._expression = expression;
this._args = args;
}
Object.defineProperty(InvocationExpression.prototype, "expression", {
get: function () {
return this._expression;
},
enumerable: true,
configurable: true
});
Object.defineProperty(InvocationExpression.prototype, "args", {
get: function () {
return this._args;
},
enumerable: true,
configurable: true
});
InvocationExpression.prototype.accept = function (visitor) {
return visitor.visitInvoke(this);
};
InvocationExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitInvoke(this);
};
InvocationExpression.prototype.update = function (expression, args) {
if (expression !== this._expression || args !== this._args) {
return new InvocationExpression(expression, args);
}
return this;
};
return InvocationExpression;
})(Expression);
var FunctionCallExpression = (function (_super) {
__extends(FunctionCallExpression, _super);
function FunctionCallExpression(expression, methodName, args) {
_super.call(this, 28 /* Call */);
this._expression = expression;
this._method = methodName;
this._args = args;
}
Object.defineProperty(FunctionCallExpression.prototype, "obj", {
get: function () {
return this._expression;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FunctionCallExpression.prototype, "method", {
get: function () {
return this._method;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FunctionCallExpression.prototype, "args", {
get: function () {
return this._args;
},
enumerable: true,
configurable: true
});
FunctionCallExpression.prototype.accept = function (visitor) {
return visitor.visitCall(this);
};
FunctionCallExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitCall(this);
};
FunctionCallExpression.prototype.update = function (expression, args) {
if (expression !== this._expression || args !== this._args) {
return new FunctionCallExpression(expression, this._method, args);
}
return this;
};
return FunctionCallExpression;
})(Expression);
var IndexExpression = (function (_super) {
__extends(IndexExpression, _super);
function IndexExpression(expression, args) {
_super.call(this, 30 /* Index */);
this._expression = expression;
this._args = args;
}
Object.defineProperty(IndexExpression.prototype, "obj", {
get: function () {
return this._expression;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IndexExpression.prototype, "args", {
get: function () {
return this._args;
},
enumerable: true,
configurable: true
});
IndexExpression.prototype.accept = function (visitor) {
return visitor.visitIndex(this);
};
IndexExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitIndex(this);
};
IndexExpression.prototype.update = function (expression, args) {
if (expression !== this._expression || args !== this._args) {
return new IndexExpression(expression, args);
}
return this;
};
return IndexExpression;
})(Expression);
var NewExpression = (function (_super) {
__extends(NewExpression, _super);
function NewExpression(typeName, args) {
_super.call(this, 27 /* New */);
this._type = typeName;
this._args = args;
}
Object.defineProperty(NewExpression.prototype, "type", {
get: function () {
return this._type;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NewExpression.prototype, "args", {
get: function () {
return this._args;
},
enumerable: true,
configurable: true
});
NewExpression.prototype.accept = function (visitor) {
return visitor.visitNew(this);
};
NewExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitNew(this);
};
NewExpression.prototype.update = function (args) {
if (args !== this._args) {
return new NewExpression(this._type, args);
}
return this;
};
return NewExpression;
})(Expression);
var MemberExpression = (function (_super) {
__extends(MemberExpression, _super);
function MemberExpression(obj, memberName) {
_super.call(this, 29 /* Member */);
this._obj = obj;
this._member = memberName;
}
Object.defineProperty(MemberExpression.prototype, "obj", {
get: function () {
return this._obj;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MemberExpression.prototype, "member", {
get: function () {
return this._member;
},
enumerable: true,
configurable: true
});
MemberExpression.prototype.accept = function (visitor) {
return visitor.visitMember(this);
};
MemberExpression.prototype.acceptGeneric = function (visitor) {
return visitor.visitMember(this);
};
MemberExpression.prototype.update = function (obj) {
if (obj !== this._obj) {
return new MemberExpression(obj, this._member);
}
return this;
};
return MemberExpression;
})(Expression);
var LambdaCompiler = (function (_super) {
__extends(LambdaCompiler, _super);
function LambdaCompiler() {
_super.call(this);
this._stack = new Array();
}
Object.defineProperty(LambdaCompiler.prototype, "code", {
get: function () {
if (this._stack.length != 1)
throw new Error("invalid code generation");
return this._stack[0];
},
enumerable: true,
configurable: true
});
LambdaCompiler.prototype.visitConstant = function (node) {
var value = "";
if (typeof node.value == "string") {
value = "\"" + node.value + "\""; // TODO: escape characters
}
else if (node.value instanceof Array) {
value = JSON.stringify(node.value);
}
else if (node.value === undefined) {
value = "undefined";
}
else {
value = node.value.toString(); // TODO
}
this._stack.push(value);
return node;
};
LambdaCompiler.prototype.visitUnary = function (node) {
this.visit(node.operand);
var o = this._stack.pop();
var i = "";
switch (node.nodeType) {
case 23 /* Negate */:
i = "-";
break;
case 24 /* UnaryPlus */:
i = "+";
break;
case 22 /* Not */:
i = "!";
break;
case 25 /* OnesComplement */:
i = "~";
break;
}
var res = "(" + i + "" + o + ")";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitBinary = function (node) {
this.visit(node.left);
this.visit(node.right);
var r = this._stack.pop();
var l = this._stack.pop();
var i = "";
switch (node.nodeType) {
case 3 /* Add */:
i = "+";
break;
case 4 /* Subtract */:
i = "-";
break;
case 5 /* Multiply */:
i = "*";
break;
case 6 /* Divide */:
i = "/";
break;
case 7 /* Modulo */:
i = "%";
break;
case 8 /* And */:
i = "&";
break;
case 9 /* Or */:
i = "|";
break;
case 10 /* AndAlso */:
i = "&&";
break;
case 11 /* OrElse */:
i = "||";
break;
case 12 /* ExclusiveOr */:
i = "^";
break;
case 13 /* Equal */:
i = "===";
break;
case 14 /* NotEqual */:
i = "!==";
break;
case 15 /* LessThan */:
i = "<";
break;
case 16 /* LessThanOrEqual */:
i = "<=";
break;
case 17 /* GreaterThan */:
i = ">";
break;
case 18 /* GreaterThanOrEqual */:
i = ">=";
break;
case 19 /* LeftShift */:
i = "<<";
break;
case 20 /* RightShift */:
i = ">>";
break;
}
var res = "(" + l + " " + i + " " + r + ")";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitConditional = function (node) {
this.visit(node.test);
this.visit(node.ifTrue);
this.visit(node.ifFalse);
var f = this._stack.pop();
var t = this._stack.pop();
var c = this._stack.pop();
var res = "(" + c + " ? " + t + " : " + f + ")";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitParameter = function (node) {
this._stack.push(node.name);
return node;
};
LambdaCompiler.prototype.visitLambda = function (node) {
this.visitMany(node.parameters);
this.visit(node.body);
var body = this._stack.pop();
var n = node.parameters.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var allArgs = args.join(", ");
var res = "function(" + allArgs + ") { return " + body + "; }";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitInvoke = function (node) {
this.visit(node.expression);
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
var func = this._stack.pop();
var res = func + "(" + argList + ")";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitCall = function (node) {
var res = "";
if (node.obj !== null) {
this.visit(node.obj);
res = this._stack.pop() + ".";
}
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
res += node.method + "(" + argList + ")";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitNew = function (node) {
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
var res = "new " + node.type + "(" + argList + ")";
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitMember = function (node) {
var res = "";
if (node.obj !== null) {
this.visit(node.obj);
res = this._stack.pop() + ".";
}
res += node.member;
this._stack.push(res);
return node;
};
LambdaCompiler.prototype.visitIndex = function (node) {
this.visit(node.obj);
var res = this._stack.pop();
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
res += "[" + argList + "]";
this._stack.push(res);
return node;
};
return LambdaCompiler;
})(ExpressionVisitor);
var FreeVariableScanner = (function (_super) {
__extends(FreeVariableScanner, _super);
function FreeVariableScanner() {
_super.call(this);
this._stack = new Array();
this._result = new Array();
}
Object.defineProperty(FreeVariableScanner.prototype, "result", {
get: function () {
return this._result;
},
enumerable: true,
configurable: true
});
FreeVariableScanner.prototype.visitParameter = function (node) {
var found = false;
for (var i = this._stack.length - 1; i >= 0; i--) {
if (this._stack[i].indexOf(node) >= 0) {
found = true;
break;
}
}
if (!found) {
this._result.push(node);
}
return node;
};
FreeVariableScanner.prototype.visitLambda = function (node) {
this._stack.push(node.parameters);
this.visit(node.body);
this._stack.pop();
return node;
};
return FreeVariableScanner;
})(ExpressionVisitor);
var ExpressionType;
(function (ExpressionType) {
ExpressionType[ExpressionType["Constant"] = 0] = "Constant";
ExpressionType[ExpressionType["Parameter"] = 1] = "Parameter";
ExpressionType[ExpressionType["Lambda"] = 2] = "Lambda";
ExpressionType[ExpressionType["Add"] = 3] = "Add";
ExpressionType[ExpressionType["Subtract"] = 4] = "Subtract";
ExpressionType[ExpressionType["Multiply"] = 5] = "Multiply";
ExpressionType[ExpressionType["Divide"] = 6] = "Divide";
ExpressionType[ExpressionType["Modulo"] = 7] = "Modulo";
ExpressionType[ExpressionType["And"] = 8] = "And";
ExpressionType[ExpressionType["Or"] = 9] = "Or";
ExpressionType[ExpressionType["AndAlso"] = 10] = "AndAlso";
ExpressionType[ExpressionType["OrElse"] = 11] = "OrElse";
ExpressionType[ExpressionType["ExclusiveOr"] = 12] = "ExclusiveOr";
ExpressionType[ExpressionType["Equal"] = 13] = "Equal";
ExpressionType[ExpressionType["NotEqual"] = 14] = "NotEqual";
ExpressionType[ExpressionType["LessThan"] = 15] = "LessThan";
ExpressionType[ExpressionType["LessThanOrEqual"] = 16] = "LessThanOrEqual";
ExpressionType[ExpressionType["GreaterThan"] = 17] = "GreaterThan";
ExpressionType[ExpressionType["GreaterThanOrEqual"] = 18] = "GreaterThanOrEqual";
ExpressionType[ExpressionType["LeftShift"] = 19] = "LeftShift";
ExpressionType[ExpressionType["RightShift"] = 20] = "RightShift";
ExpressionType[ExpressionType["Invoke"] = 21] = "Invoke";
ExpressionType[ExpressionType["Not"] = 22] = "Not";
ExpressionType[ExpressionType["Negate"] = 23] = "Negate";
ExpressionType[ExpressionType["UnaryPlus"] = 24] = "UnaryPlus";
ExpressionType[ExpressionType["OnesComplement"] = 25] = "OnesComplement";
ExpressionType[ExpressionType["Condition"] = 26] = "Condition";
ExpressionType[ExpressionType["New"] = 27] = "New";
ExpressionType[ExpressionType["Call"] = 28] = "Call";
ExpressionType[ExpressionType["Member"] = 29] = "Member";
ExpressionType[ExpressionType["Index"] = 30] = "Index";
})(ExpressionType || (ExpressionType = {}));
var Binder = (function (_super) {
__extends(Binder, _super);
function Binder(resources) {
_super.call(this);
this._stack = new Array();
this._resources = resources;
}
Binder.prototype.visitParameter = function (node) {
var found = false;
for (var i = this._stack.length - 1; i >= 0; i--) {
if (this._stack[i].indexOf(node) >= 0) {
found = true;
break;
}
}
if (!found) {
return Expression.constant(this._resources[node.name]);
}
return node;
};
Binder.prototype.visitLambda = function (node) {
this._stack.push(node.parameters);
this.visit(node.body);
this._stack.pop();
return node;
};
return Binder;
})(ExpressionVisitor);
var PrintVisitor = (function (_super) {
__extends(PrintVisitor, _super);
function PrintVisitor() {
_super.apply(this, arguments);
}
PrintVisitor.prototype.visitConstant = function (node) {
return "Constant(" + node.value + ")";
};
PrintVisitor.prototype.visitParameter = function (node) {
return "Parameter(" + node.name + ")";
};
PrintVisitor.prototype.visitBinary = function (node) {
return ExpressionType[node.nodeType] + "(" + this.visit(node.left) + ", " + this.visit(node.right) + ")";
};
PrintVisitor.prototype.visitUnary = function (node) {
return ExpressionType[node.nodeType] + "(" + this.visit(node.operand) + ")";
};
PrintVisitor.prototype.visitConditional = function (node) {
return "Conditional(" + this.visit(node.test) + ", " + this.visit(node.ifTrue) + ", " + this.visit(node.ifFalse) + ")";
};
PrintVisitor.prototype.visitLambda = function (node) {
var body = this.visit(node.body);
var children = this.visitMany(node.parameters);
children.unshift(body);
return "Lambda(" + children.join(", ") + ")";
};
PrintVisitor.prototype.visitInvoke = function (node) {
var expression = this.visit(node.expression);
var children = this.visitMany(node.args);
children.unshift(expression);
return "Invoke(" + children.join(", ") + ")";
};
PrintVisitor.prototype.visitCall = function (node) {
var children = this.visitMany(node.args);
if (node.obj != null) {
children.unshift(this.visit(node.obj));
}
children.unshift(node.method);
return "Call(" + children.join(", ") + ")";
};
PrintVisitor.prototype.visitNew = function (node) {
var children = this.visitMany(node.args);
children.unshift(node.type);
return "New(" + children.join(", ") + ")";
};
PrintVisitor.prototype.visitMember = function (node) {
var children = [];
if (node.obj != null) {
children.unshift(this.visit(node.obj));
}
children.unshift(node.member);
return "Member(" + children.join(", ") + ")";
};
PrintVisitor.prototype.visitIndex = function (node) {
var children = this.visitMany(node.args);
if (node.obj != null) {
children.unshift(this.visit(node.obj));
}
return "Index(" + children.join(", ") + ")";
};
return PrintVisitor;
})(ExpressionVisitorGeneric);
var BonsaiVisitor = (function (_super) {
__extends(BonsaiVisitor, _super);
function BonsaiVisitor() {
_super.apply(this, arguments);
}
BonsaiVisitor.prototype.visitConstant = function (node) {
return [":", node.value];
};
BonsaiVisitor.prototype.visitParameter = function (node) {
return ["$", node.name];
};
BonsaiVisitor.prototype.visitBinary = function (node) {
var i = "";
switch (node.nodeType) {
case 3 /* Add */:
i = "+";
break;
case 4 /* Subtract */:
i = "-";
break;
case 5 /* Multiply */:
i = "*";
break;
case 6 /* Divide */:
i = "/";
break;
case 7 /* Modulo */:
i = "%";
break;
case 8 /* And */:
i = "&";
break;
case 9 /* Or */:
i = "|";
break;
case 10 /* AndAlso */:
i = "&&";
break;
case 11 /* OrElse */:
i = "||";
break;
case 12 /* ExclusiveOr */:
i = "^";
break;
case 13 /* Equal */:
i = "===";
break;
case 14 /* NotEqual */:
i = "!==";
break;
case 15 /* LessThan */:
i = "<";
break;
case 16 /* LessThanOrEqual */:
i = "<=";
break;
case 17 /* GreaterThan */:
i = ">";
break;
case 18 /* GreaterThanOrEqual */:
i = ">=";
break;
case 19 /* LeftShift */:
i = "<<";
break;
case 20 /* RightShift */:
i = ">>";
break;
}
return [i, this.visit(node.left), this.visit(node.right)];
};
BonsaiVisitor.prototype.visitUnary = function (node) {
var i = "";
switch (node.nodeType) {
case 23 /* Negate */:
i = "-";
break;
case 24 /* UnaryPlus */:
i = "+";
break;
case 22 /* Not */:
i = "!";
break;
case 25 /* OnesComplement */:
i = "~";
break;
}
return [i, this.visit(node.operand)];
};
BonsaiVisitor.prototype.visitConditional = function (node) {
return ["?:", this.visit(node.test), this.visit(node.ifTrue), this.visit(node.ifFalse)];
};
BonsaiVisitor.prototype.visitLambda = function (node) {
return ["=>", this.visit(node.body), this.visitMany(node.parameters)];
};
BonsaiVisitor.prototype.visitInvoke = function (node) {
var expression = this.visit(node.expression);
var args = this.visitMany(node.args);
return ["()", expression, args];
};
BonsaiVisitor.prototype.visitCall = function (node) {
var args = [];
if (node.obj != null) {
args.unshift(this.visit(node.obj));
}
args.unshift(this.visitMany(node.args));
return [".()", node.method, args];
};
BonsaiVisitor.prototype.visitNew = function (node) {
var args = this.visitMany(node.args);
return ["new", args];
};
BonsaiVisitor.prototype.visitMember = function (node) {
var res = [".", node.member];
if (node.obj != null) {
res.unshift(this.visit(node.obj));
}
return res;
};
BonsaiVisitor.prototype.visitIndex = function (node) {
throw new Error("not implemented");
};
return BonsaiVisitor;
})(ExpressionVisitorGeneric);
//# sourceMappingURL=compiler.js.map
================================================
FILE: src/core/expressions/compiler.ts
================================================
class Expression {
nodeType: ExpressionType;
constructor(nodeType: ExpressionType) {
this.nodeType = nodeType;
}
accept(visitor: ExpressionVisitor): Expression {
throw new Error("not implemented");
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
throw new Error("not implemented");
}
toString(): string {
return new PrintVisitor().visit(this);
}
toBonsai(): string {
return new BonsaiVisitor().visit(this);
}
static constant(value: any): ConstantExpression {
return new ConstantExpression(value);
}
static parameter(name: string): ParameterExpression {
return new ParameterExpression(name);
}
static condition(test: Expression, ifTrue: Expression, ifFalse: Expression): ConditionalExpression {
return new ConditionalExpression(test, ifTrue, ifFalse);
}
static add(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Add, left, right);
}
static subtract(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Subtract, left, right);
}
static multiply(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Multiply, left, right);
}
static divide(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Divide, left, right);
}
static modulo(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Modulo, left, right);
}
static and(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.And, left, right);
}
static andAlso(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.AndAlso, left, right);
}
static or(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Or, left, right);
}
static orElse(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.OrElse, left, right);
}
static exclusiveOr(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.ExclusiveOr, left, right);
}
static equal(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.Equal, left, right);
}
static notEqual(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.NotEqual, left, right);
}
static lessThan(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.LessThan, left, right);
}
static lessThanOrEqual(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.LessThanOrEqual, left, right);
}
static greaterThan(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.GreaterThan, left, right);
}
static greaterThanOrEqual(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.GreaterThanOrEqual, left, right);
}
static leftShift(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.LeftShift, left, right);
}
static rightShift(left: Expression, right: Expression): BinaryExpression {
return new BinaryExpression(ExpressionType.RightShift, left, right);
}
static not(operand: Expression): UnaryExpression {
return new UnaryExpression(ExpressionType.Not, operand);
}
static unaryPlus(operand: Expression): UnaryExpression {
return new UnaryExpression(ExpressionType.UnaryPlus, operand);
}
static negate(operand: Expression): UnaryExpression {
return new UnaryExpression(ExpressionType.Negate, operand);
}
static onesComplement(operand: Expression): UnaryExpression {
return new UnaryExpression(ExpressionType.OnesComplement, operand);
}
static lambda(body: Expression, ...parameters: ParameterExpression[]): LambdaExpression {
return new LambdaExpression(body, parameters);
}
static invoke(expression: Expression, ...args: Expression[]): InvocationExpression {
return new InvocationExpression(expression, args);
}
static new(typeName: string, ...args: Expression[]): NewExpression {
return new NewExpression(typeName, args);
}
static functionCall(obj: Expression, methodName: string, ...args: Expression[]): FunctionCallExpression {
return new FunctionCallExpression(obj, methodName, args);
}
static member(obj: Expression, memberName: string): MemberExpression {
return new MemberExpression(obj, memberName);
}
static index(obj: Expression, ...args: Expression[]): IndexExpression {
return new IndexExpression(obj, args);
}
}
class ExpressionVisitorGeneric {
visit(node: Expression): T {
if (node === null) {
return null;
}
return node.acceptGeneric(this);
}
visitConstant(node: ConstantExpression): T { throw new Error("not implemented"); }
visitParameter(node: ParameterExpression): T { throw new Error("not implemented"); }
visitBinary(node: BinaryExpression): T { throw new Error("not implemented"); }
visitUnary(node: UnaryExpression): T { throw new Error("not implemented"); }
visitConditional(node: ConditionalExpression): T { throw new Error("not implemented"); }
visitLambda(node: LambdaExpression): T { throw new Error("not implemented"); }
visitInvoke(node: InvocationExpression): T { throw new Error("not implemented"); }
visitCall(node: FunctionCallExpression): T { throw new Error("not implemented"); }
visitNew(node: NewExpression): T { throw new Error("not implemented"); }
visitMember(node: MemberExpression): T { throw new Error("not implemented"); }
visitIndex(node: IndexExpression): T { throw new Error("not implemented"); }
visitMany(nodes: E[]): T[] {
var res = new Array(nodes.length);
for (var i = 0; i < nodes.length; i++) {
var oldNode = nodes[i];
var newNode = this.visit(oldNode);
res[i] = newNode;
}
return res;
}
}
class ExpressionVisitor {
visit(node: Expression): Expression {
if (node === null) {
return null;
}
return node.accept(this);
}
visitConstant(node: ConstantExpression): Expression {
return node;
}
visitParameter(node: ParameterExpression): Expression {
return node;
}
visitBinary(node: BinaryExpression): Expression {
return node.update(this.visit(node.left), this.visit(node.right));
}
visitUnary(node: UnaryExpression): Expression {
return node.update(this.visit(node.operand));
}
visitConditional(node: ConditionalExpression): Expression {
return node.update(this.visit(node.test), this.visit(node.ifTrue), this.visit(node.ifFalse));
}
visitLambda(node: LambdaExpression): Expression {
return node.update(this.visit(node.body), this.visitMany(node.parameters));
}
visitInvoke(node: InvocationExpression): Expression {
return node.update(this.visit(node.expression), this.visitMany(node.args));
}
visitCall(node: FunctionCallExpression): Expression {
return node.update(this.visit(node.obj), this.visitMany(node.args));
}
visitNew(node: NewExpression): Expression {
return node.update(this.visitMany(node.args));
}
visitMember(node: MemberExpression): Expression {
return node.update(this.visit(node.obj));
}
visitIndex(node: IndexExpression): Expression {
return node.update(this.visit(node.obj), this.visitMany(node.args));
}
visitMany(nodes: T[]): T[] {
var res = new Array(nodes.length);
for (var i = 0; i < nodes.length; i++) {
var oldNode = nodes[i];
var newNode = this.visit(oldNode);
res[i] = newNode;
}
return res;
}
}
class ConstantExpression extends Expression {
_value: any;
constructor(value: any) {
super(ExpressionType.Constant);
this._value = value;
}
get value(): any {
return this._value;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitConstant(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitConstant(this);
}
}
class ParameterExpression extends Expression {
_name: string;
constructor(name: string) {
super(ExpressionType.Parameter);
this._name = name;
}
get name(): string {
return this._name;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitParameter(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitParameter(this);
}
}
class UnaryExpression extends Expression {
_operand: Expression;
constructor(nodeType: ExpressionType, operand: Expression) {
super(nodeType);
this._operand = operand;
}
get operand(): Expression {
return this._operand;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitUnary(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitUnary(this);
}
update(operand: Expression): UnaryExpression {
if (operand !== this._operand) {
return new UnaryExpression(this.nodeType, operand);
}
return this;
}
}
class BinaryExpression extends Expression {
_left: Expression;
_right: Expression;
constructor(nodeType: ExpressionType, left: Expression, right: Expression) {
super(nodeType);
this._left = left;
this._right = right;
}
get left(): Expression {
return this._left;
}
get right(): Expression {
return this._right;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitBinary(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitBinary(this);
}
update(left: Expression, right: Expression): BinaryExpression {
if (left !== this._left || right !== this._right) {
return new BinaryExpression(this.nodeType, left, right);
}
return this;
}
}
class ConditionalExpression extends Expression {
_test: Expression;
_ifTrue: Expression;
_ifFalse: Expression;
constructor(test: Expression, ifTrue: Expression, ifFalse: Expression) {
super(ExpressionType.Condition);
this._test = test;
this._ifTrue = ifTrue;
this._ifFalse = ifFalse;
}
get test(): Expression {
return this._test;
}
get ifTrue(): Expression {
return this._ifTrue;
}
get ifFalse(): Expression {
return this._ifTrue;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitConditional(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitConditional(this);
}
update(test: Expression, ifTrue: Expression, ifFalse: Expression): ConditionalExpression {
if (test !== this._test || ifTrue !== this._ifTrue || ifFalse !== this._ifFalse) {
return new ConditionalExpression(test, ifTrue, ifFalse);
}
return this;
}
}
class LambdaExpression extends Expression {
_body: Expression;
_parameters: ParameterExpression[];
constructor(body: Expression, parameters: ParameterExpression[]) {
super(ExpressionType.Lambda);
this._body = body;
this._parameters = parameters;
}
get body(): Expression {
return this._body;
}
get parameters(): ParameterExpression[] {
return this._parameters;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitLambda(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitLambda(this);
}
update(body: Expression, parameters: ParameterExpression[]): LambdaExpression {
if (body !== this._body || parameters !== this._parameters) {
return new LambdaExpression(body, parameters);
}
return this;
}
compileToFunction(debug?: boolean): string {
var comp = new LambdaCompiler();
comp.visit(this);
var code = comp.code;
code = code.replace(/"/g, "\\\""); // TODO: more escape sequences
code = "new Function(\"return " + code + ";\")";
code = code.replace(/\r?\n|\r/g, "");
if (debug) {
alert(code);
}
return code;
}
compile(debug?: boolean): TFunction {
var code = this.compileToFunction(debug);
return eval(code)();
}
}
class InvocationExpression extends Expression {
_expression: Expression;
_args: Expression[];
constructor(expression: Expression, args: Expression[]) {
super(ExpressionType.Invoke);
this._expression = expression;
this._args = args;
}
get expression(): Expression {
return this._expression;
}
get args(): Expression[] {
return this._args;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitInvoke(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitInvoke(this);
}
update(expression: Expression, args: Expression[]): InvocationExpression {
if (expression !== this._expression || args !== this._args) {
return new InvocationExpression(expression, args);
}
return this;
}
}
class FunctionCallExpression extends Expression {
_expression: Expression;
_method: string;
_args: Expression[];
constructor(expression: Expression, methodName: string, args: Expression[]) {
super(ExpressionType.Call);
this._expression = expression;
this._method = methodName;
this._args = args;
}
get obj(): Expression {
return this._expression;
}
get method(): string {
return this._method;
}
get args(): Expression[] {
return this._args;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitCall(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitCall(this);
}
update(expression: Expression, args: Expression[]): FunctionCallExpression {
if (expression !== this._expression || args !== this._args) {
return new FunctionCallExpression(expression, this._method, args);
}
return this;
}
}
class IndexExpression extends Expression {
_expression: Expression;
_args: Expression[];
constructor(expression: Expression, args: Expression[]) {
super(ExpressionType.Index);
this._expression = expression;
this._args = args;
}
get obj(): Expression {
return this._expression;
}
get args(): Expression[] {
return this._args;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitIndex(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitIndex(this);
}
update(expression: Expression, args: Expression[]): IndexExpression {
if (expression !== this._expression || args !== this._args) {
return new IndexExpression(expression, args);
}
return this;
}
}
class NewExpression extends Expression {
_type: string;
_args: Expression[];
constructor(typeName: string, args: Expression[]) {
super(ExpressionType.New);
this._type = typeName;
this._args = args;
}
get type(): string {
return this._type;
}
get args(): Expression[] {
return this._args;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitNew(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitNew(this);
}
update(args: Expression[]): NewExpression {
if (args !== this._args) {
return new NewExpression(this._type, args);
}
return this;
}
}
class MemberExpression extends Expression {
_obj: Expression;
_member: string;
constructor(obj: Expression, memberName: string) {
super(ExpressionType.Member);
this._obj = obj;
this._member = memberName;
}
get obj(): Expression {
return this._obj;
}
get member(): string {
return this._member;
}
accept(visitor: ExpressionVisitor): Expression {
return visitor.visitMember(this);
}
acceptGeneric(visitor: ExpressionVisitorGeneric): T {
return visitor.visitMember(this);
}
update(obj: Expression): MemberExpression {
if (obj !== this._obj) {
return new MemberExpression(obj, this._member);
}
return this;
}
}
class LambdaCompiler extends ExpressionVisitor {
_stack: string[];
constructor() {
super();
this._stack = [];
}
get code(): string {
if (this._stack.length != 1)
throw new Error("invalid code generation");
return this._stack[0];
}
visitConstant(node: ConstantExpression): Expression {
var value = "";
if (typeof node.value == "string") {
value = "\"" + node.value + "\""; // TODO: escape characters
}
else if (node.value instanceof Array) {
value = JSON.stringify(node.value);
}
else if (node.value === undefined) {
value = "undefined";
}
else {
value = node.value.toString(); // TODO
}
this._stack.push(value);
return node;
}
visitUnary(node: UnaryExpression): Expression {
this.visit(node.operand);
var o = this._stack.pop();
var i = "";
switch (node.nodeType) {
case ExpressionType.Negate:
i = "-";
break;
case ExpressionType.UnaryPlus:
i = "+";
break;
case ExpressionType.Not:
i = "!";
break;
case ExpressionType.OnesComplement:
i = "~";
break;
}
var res = "(" + i + "" + o + ")";
this._stack.push(res);
return node;
}
visitBinary(node: BinaryExpression): Expression {
this.visit(node.left);
this.visit(node.right);
var r = this._stack.pop();
var l = this._stack.pop();
var i = "";
switch (node.nodeType) {
case ExpressionType.Add:
i = "+";
break;
case ExpressionType.Subtract:
i = "-";
break;
case ExpressionType.Multiply:
i = "*";
break;
case ExpressionType.Divide:
i = "/";
break;
case ExpressionType.Modulo:
i = "%";
break;
case ExpressionType.And:
i = "&";
break;
case ExpressionType.Or:
i = "|";
break;
case ExpressionType.AndAlso:
i = "&&";
break;
case ExpressionType.OrElse:
i = "||";
break;
case ExpressionType.ExclusiveOr:
i = "^";
break;
case ExpressionType.Equal:
i = "===";
break;
case ExpressionType.NotEqual:
i = "!==";
break;
case ExpressionType.LessThan:
i = "<";
break;
case ExpressionType.LessThanOrEqual:
i = "<=";
break;
case ExpressionType.GreaterThan:
i = ">";
break;
case ExpressionType.GreaterThanOrEqual:
i = ">=";
break;
case ExpressionType.LeftShift:
i = "<<";
break;
case ExpressionType.RightShift:
i = ">>";
break;
}
var res = "(" + l + " " + i + " " + r + ")";
this._stack.push(res);
return node;
}
visitConditional(node: ConditionalExpression): Expression {
this.visit(node.test);
this.visit(node.ifTrue);
this.visit(node.ifFalse);
var f = this._stack.pop();
var t = this._stack.pop();
var c = this._stack.pop();
var res = "(" + c + " ? " + t + " : " + f + ")";
this._stack.push(res);
return node;
}
visitParameter(node: ParameterExpression): Expression {
this._stack.push(node.name);
return node;
}
visitLambda(node: LambdaExpression): Expression {
this.visitMany(node.parameters);
this.visit(node.body);
var body = this._stack.pop();
var n = node.parameters.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var allArgs = args.join(", ");
var res = "function(" + allArgs + ") { return " + body + "; }";
this._stack.push(res);
return node;
}
visitInvoke(node: InvocationExpression): Expression {
this.visit(node.expression);
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
var func = this._stack.pop();
var res = func + "(" + argList + ")";
this._stack.push(res);
return node;
}
visitCall(node: FunctionCallExpression): Expression {
var res = "";
if (node.obj !== null) {
this.visit(node.obj);
res = this._stack.pop() + ".";
}
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
res += node.method + "(" + argList + ")";
this._stack.push(res);
return node;
}
visitNew(node: NewExpression): Expression {
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
var res = "new " + node.type + "(" + argList + ")";
this._stack.push(res);
return node;
}
visitMember(node: MemberExpression): Expression {
var res = "";
if (node.obj !== null) {
this.visit(node.obj);
res = this._stack.pop() + ".";
}
res += node.member;
this._stack.push(res);
return node;
}
visitIndex(node: IndexExpression): Expression {
this.visit(node.obj);
var res = this._stack.pop();
this.visitMany(node.args);
var n = node.args.length;
var args = new Array(n);
for (var i = 0; i < n; i++) {
args[n - i - 1] = this._stack.pop();
}
var argList = args.join(", ");
res += "[" + argList + "]";
this._stack.push(res);
return node;
}
}
class FreeVariableScanner extends ExpressionVisitor {
_stack: Expression[][];
_result: Expression[];
constructor() {
super();
this._stack = [];
this._result = [];
}
get result(): Expression[] {
return this._result;
}
visitParameter(node: ParameterExpression): Expression {
var found = false;
for (var i = this._stack.length - 1; i >= 0; i--) {
if (this._stack[i].indexOf(node) >= 0) {
found = true;
break;
}
}
if (!found) {
this._result.push(node);
}
return node;
}
visitLambda(node: LambdaExpression): Expression {
this._stack.push(node.parameters);
this.visit(node.body);
this._stack.pop();
return node;
}
}
enum ExpressionType {
Constant,
Parameter,
Lambda,
Add,
Subtract,
Multiply,
Divide,
Modulo,
And,
Or,
AndAlso,
OrElse,
ExclusiveOr,
Equal,
NotEqual,
LessThan,
LessThanOrEqual,
GreaterThan,
GreaterThanOrEqual,
LeftShift,
RightShift,
Invoke,
Not,
Negate,
UnaryPlus,
OnesComplement,
Condition,
New,
Call,
Member,
Index,
}
class Binder extends ExpressionVisitor {
_stack: Expression[][];
_resources: any;
constructor(resources: any) {
super();
this._stack = [];
this._resources = resources;
}
visitParameter(node: ParameterExpression): Expression {
var found = false;
for (var i = this._stack.length - 1; i >= 0; i--) {
if (this._stack[i].indexOf(node) >= 0) {
found = true;
break;
}
}
if (!found) {
return Expression.constant(this._resources[node.name]);
}
return node;
}
visitLambda(node: LambdaExpression): Expression {
this._stack.push(node.parameters);
this.visit(node.body);
this._stack.pop();
return node;
}
}
class PrintVisitor extends ExpressionVisitorGeneric {
visitConstant(node: ConstantExpression): string {
return "Constant(" + node.value + ")";
}
visitParameter(node: ParameterExpression): string {
return "Parameter(" + node.name + ")";
}
visitBinary(node: BinaryExpression): string {
return ExpressionType[node.nodeType] + "(" + this.visit(node.left) + ", " + this.visit(node.right) + ")";
}
visitUnary(node: UnaryExpression): string {
return ExpressionType[node.nodeType] + "(" + this.visit(node.operand) + ")";
}
visitConditional(node: ConditionalExpression): string {
return "Conditional(" + this.visit(node.test) + ", " + this.visit(node.ifTrue) + ", " + this.visit(node.ifFalse) + ")";
}
visitLambda(node: LambdaExpression): string {
var body = this.visit(node.body);
var children = this.visitMany(node.parameters);
children.unshift(body);
return "Lambda(" + children.join(", ") + ")";
}
visitInvoke(node: InvocationExpression): string {
var expression = this.visit(node.expression);
var children = this.visitMany(node.args);
children.unshift(expression);
return "Invoke(" + children.join(", ") + ")";
}
visitCall(node: FunctionCallExpression): string {
var children = this.visitMany(node.args);
if (node.obj != null) {
children.unshift(this.visit(node.obj));
}
children.unshift(node.method);
return "Call(" + children.join(", ") + ")";
}
visitNew(node: NewExpression): string {
var children = this.visitMany(node.args);
children.unshift(node.type);
return "New(" + children.join(", ") + ")";
}
visitMember(node: MemberExpression): string {
var children = [];
if (node.obj != null) {
children.unshift(this.visit(node.obj));
}
children.unshift(node.member);
return "Member(" + children.join(", ") + ")";
}
visitIndex(node: IndexExpression): string {
var children = this.visitMany(node.args);
if (node.obj != null) {
children.unshift(this.visit(node.obj));
}
return "Index(" + children.join(", ") + ")";
}
}
class BonsaiVisitor extends ExpressionVisitorGeneric {
visitConstant(node: ConstantExpression): any {
return [ ":", node.value ];
}
visitParameter(node: ParameterExpression): any {
return ["$", node.name];
}
visitBinary(node: BinaryExpression): any {
var i = "";
switch (node.nodeType) {
case ExpressionType.Add:
i = "+";
break;
case ExpressionType.Subtract:
i = "-";
break;
case ExpressionType.Multiply:
i = "*";
break;
case ExpressionType.Divide:
i = "/";
break;
case ExpressionType.Modulo:
i = "%";
break;
case ExpressionType.And:
i = "&";
break;
case ExpressionType.Or:
i = "|";
break;
case ExpressionType.AndAlso:
i = "&&";
break;
case ExpressionType.OrElse:
i = "||";
break;
case ExpressionType.ExclusiveOr:
i = "^";
break;
case ExpressionType.Equal:
i = "===";
break;
case ExpressionType.NotEqual:
i = "!==";
break;
case ExpressionType.LessThan:
i = "<";
break;
case ExpressionType.LessThanOrEqual:
i = "<=";
break;
case ExpressionType.GreaterThan:
i = ">";
break;
case ExpressionType.GreaterThanOrEqual:
i = ">=";
break;
case ExpressionType.LeftShift:
i = "<<";
break;
case ExpressionType.RightShift:
i = ">>";
break;
}
return [ i, this.visit(node.left), this.visit(node.right) ];
}
visitUnary(node: UnaryExpression): any {
var i = "";
switch (node.nodeType) {
case ExpressionType.Negate:
i = "-";
break;
case ExpressionType.UnaryPlus:
i = "+";
break;
case ExpressionType.Not:
i = "!";
break;
case ExpressionType.OnesComplement:
i = "~";
break;
}
return [i, this.visit(node.operand)];
}
visitConditional(node: ConditionalExpression): any {
return ["?:", this.visit(node.test), this.visit(node.ifTrue), this.visit(node.ifFalse) ];
}
visitLambda(node: LambdaExpression): any {
return ["=>", this.visit(node.body), this.visitMany(node.parameters)];
}
visitInvoke(node: InvocationExpression): any {
var expression = this.visit(node.expression);
var args = this.visitMany(node.args);
return ["()", expression, args];
}
visitCall(node: FunctionCallExpression): any {
var args = [];
if (node.obj != null) {
args.unshift(this.visit(node.obj));
}
args.unshift(this.visitMany(node.args));
return [".()", node.method, args];
}
visitNew(node: NewExpression): any {
var args = this.visitMany(node.args);
return ["new", args];
}
visitMember(node: MemberExpression): any {
var res = [".", node.member];
if (node.obj != null) {
res.unshift(this.visit(node.obj));
}
return res;
}
visitIndex(node: IndexExpression): any {
throw new Error("not implemented");
}
}
================================================
FILE: src/core/expressions/index.html
================================================
TypeScript Expression APIs
TypeScript Expression APIs
================================================
FILE: src/core/expressions/web.Debug.config
================================================
================================================
FILE: src/core/expressions/web.Release.config
================================================
================================================
FILE: src/core/expressions/web.config
================================================
================================================
FILE: src/core/headers/aggregatesheader.js
================================================
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
BinaryDisposable = Rx.BinaryDisposable,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
disposableEmpty = Rx.Disposable.empty,
helpers = Rx.helpers,
defaultComparer = helpers.defaultComparer,
identity = helpers.identity,
defaultSubComparer = helpers.defaultSubComparer,
isFunction = helpers.isFunction,
isPromise = helpers.isPromise,
isArrayLike = helpers.isArrayLike,
isIterable = helpers.isIterable,
inherits = Rx.internals.inherits,
observableFromPromise = Observable.fromPromise,
observableFrom = Observable.from,
bindCallback = Rx.internals.bindCallback,
EmptyError = Rx.EmptyError,
ObservableBase = Rx.ObservableBase,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
================================================
FILE: src/core/headers/asyncheader.js
================================================
// Aliases
var Observable = Rx.Observable,
observableFromPromise = Observable.fromPromise,
observableThrow = Observable.throwError,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AsyncSubject = Rx.AsyncSubject,
disposableCreate = Rx.Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
immediateScheduler = Rx.Scheduler.immediate,
defaultScheduler = Rx.Scheduler['default'],
inherits = Rx.internals.inherits,
isScheduler = Rx.Scheduler.isScheduler,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike;
================================================
FILE: src/core/headers/asyncintro.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.binding', 'exports'], function (Rx, exports) {
root.Rx = factory(root, exports, Rx);
return root.Rx;
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/backpressureheader.js
================================================
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
NAryDisposable = Rx.NAryDisposable,
Notification = Rx.Notification,
Subject = Rx.Subject,
Observer = Rx.Observer,
disposableEmpty = Rx.Disposable.empty,
disposableCreate = Rx.Disposable.create,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
defaultScheduler = Rx.Scheduler['default'],
currentThreadScheduler = Rx.Scheduler.currentThread,
identity = Rx.helpers.identity,
isScheduler = Rx.Scheduler.isScheduler,
isFunction = Rx.helpers.isFunction,
checkDisposed = Rx.Disposable.checkDisposed;
================================================
FILE: src/core/headers/basicheader-compat.js
================================================
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
================================================
FILE: src/core/headers/basicheader.js
================================================
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) { for(var a = [], i = 0, len = arr.length; i < len; i++) { a.push(arr[i]); } return a;}
================================================
FILE: src/core/headers/bindingheader.js
================================================
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
Subject = Rx.Subject,
AsyncSubject = Rx.AsyncSubject,
Observer = Rx.Observer,
ScheduledObserver = Rx.internals.ScheduledObserver,
disposableCreate = Rx.Disposable.create,
disposableEmpty = Rx.Disposable.empty,
BinaryDisposable = Rx.BinaryDisposable,
currentThreadScheduler = Rx.Scheduler.currentThread,
isFunction = Rx.helpers.isFunction,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
checkDisposed = Rx.Disposable.checkDisposed;
// Utilities
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
================================================
FILE: src/core/headers/coincidenceheader.js
================================================
var Observable = Rx.Observable,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
Subject = Rx.Subject,
observableProto = Observable.prototype,
observableEmpty = Observable.empty,
observableNever = Observable.never,
AnonymousObservable = Rx.AnonymousObservable,
addRef = Rx.internals.addRef,
inherits = Rx.internals.inherits,
bindCallback = Rx.internals.bindCallback,
noop = Rx.helpers.noop,
isPromise = Rx.helpers.isPromise,
isFunction = Rx.helpers.isFunction,
observableFromPromise = Observable.fromPromise;
================================================
FILE: src/core/headers/core-bindingheader.js
================================================
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
Observer = Rx.Observer,
AbstractObserver = Rx.internals.AbstractObserver,
disposableCreate = Rx.Disposable.create,
disposableEmpty = Rx.Disposable.empty,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
SerialDisposable = Rx.SerialDisposable,
currentThreadScheduler = Rx.Scheduler.currentThread,
isFunction = Rx.helpers.isFunction,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
checkDisposed = Rx.Disposable.checkDisposed;
// Utilities
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
================================================
FILE: src/core/headers/core-intro.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.core'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx.core'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/core-testheader.js
================================================
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
notImplemented = Rx.helpers.notImplemented,
defaultComparer = Rx.helpers.defaultComparer = function (a, b) { return isEqual(a, b); };
================================================
FILE: src/core/headers/coreheader.js
================================================
// Defaults
var
noop = Rx.helpers.noop = function () { },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && !isFunction(p.subscribe) && isFunction(p.then); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); }
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Error.prototype;
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Error.prototype;
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
================================================
FILE: src/core/headers/enumeratorheader.js
================================================
// Shim in iterator support
var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (root.Set && typeof new root.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined };
var isIterable = Rx.helpers.isIterable = function (o) {
return o && o[$iterator$] !== undefined;
};
var isArrayLike = Rx.helpers.isArrayLike = function (o) {
return o && o.length !== undefined;
};
Rx.helpers.iterator = $iterator$;
================================================
FILE: src/core/headers/experimentalheader.js
================================================
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
ObservableBase = Rx.ObservableBase,
AbstractObserver = Rx.internals.AbstractObserver,
FlatMapObservable = Rx.FlatMapObservable,
observableConcat = Observable.concat,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
disposableEmpty = Rx.Disposable.empty,
CompositeDisposable = Rx.CompositeDisposable,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
Enumerable = Rx.internals.Enumerable,
enumerableOf = Enumerable.of,
currentThreadScheduler = Rx.Scheduler.currentThread,
AsyncSubject = Rx.AsyncSubject,
Observer = Rx.Observer,
inherits = Rx.internals.inherits,
addProperties = Rx.internals.addProperties,
helpers = Rx.helpers,
noop = helpers.noop,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isIterable = Rx.helpers.isIterable,
isArrayLike = Rx.helpers.isArrayLike,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
================================================
FILE: src/core/headers/exports.js
================================================
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
root.Rx = Rx;
define(function() {
return Rx;
});
} else if (freeExports && freeModule) {
// in Node.js or RingoJS
if (moduleExports) {
(freeModule.exports = Rx).Rx = Rx;
} else {
freeExports.Rx = Rx;
}
} else {
// in a browser or Rhino
root.Rx = Rx;
}
================================================
FILE: src/core/headers/intro.js
================================================
;(function (undefined) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
var Rx = {
internals: {},
config: {
Promise: root.Promise
},
helpers: { }
};
================================================
FILE: src/core/headers/joinpatternsheader.js
================================================
// Aliases
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
observableThrow = Observable.throwError,
observerCreate = Rx.Observer.create,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
AbstractObserver = Rx.internals.AbstractObserver,
noop = Rx.helpers.noop,
inherits = Rx.internals.inherits,
isFunction = Rx.helpers.isFunction;
================================================
FILE: src/core/headers/license.js
================================================
// Copyright (c) Microsoft, All rights reserved. See License.txt in the project root for license information.
================================================
FILE: src/core/headers/liteextrasheader.js
================================================
// References
var Observable = Rx.Observable,
observableProto = Observable.prototype,
observableNever = Observable.never,
observableThrow = Observable['throw'],
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
AnonymousObserver = Rx.AnonymousObserver,
notificationCreateOnNext = Rx.Notification.createOnNext,
notificationCreateOnError = Rx.Notification.createOnError,
notificationCreateOnCompleted = Rx.Notification.createOnCompleted,
Observer = Rx.Observer,
observerCreate = Observer.create,
AbstractObserver = Rx.internals.AbstractObserver,
Subject = Rx.Subject,
internals = Rx.internals,
helpers = Rx.helpers,
ScheduledObserver = internals.ScheduledObserver,
SerialDisposable = Rx.SerialDisposable,
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
disposableEmpty = Rx.Disposable.empty,
immediateScheduler = Rx.Scheduler.immediate,
defaultKeySerializer = helpers.defaultKeySerializer,
addRef = Rx.internals.addRef,
identity = helpers.identity,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
inherits = internals.inherits,
bindCallback = internals.bindCallback,
noop = helpers.noop,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise,
ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError;
================================================
FILE: src/core/headers/liteheader-compat.js
================================================
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = (function () { return !!Date.now ? Date.now : function () { return +new Date; }; }()),
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
================================================
FILE: src/core/headers/liteheader.js
================================================
// Defaults
var noop = Rx.helpers.noop = function () { },
identity = Rx.helpers.identity = function (x) { return x; },
defaultNow = Rx.helpers.defaultNow = Date.now,
defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); },
defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); },
defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); },
defaultError = Rx.helpers.defaultError = function (err) { throw err; },
isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.subscribe !== 'function' && typeof p.then === 'function'; },
isFunction = Rx.helpers.isFunction = (function () {
var isFn = function (value) {
return typeof value == 'function' || false;
};
// fallback for older versions of Chrome and Safari
if (isFn(/x/)) {
isFn = function(value) {
return typeof value == 'function' && toString.call(value) == '[object Function]';
};
}
return isFn;
}());
function cloneArray(arr) {
var len = arr.length, a = new Array(len);
for(var i = 0; i < len; i++) { a[i] = arr[i]; }
return a;
}
================================================
FILE: src/core/headers/liteintro-compat.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/liteintro.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/litetestintro-compat.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.virtualtime.compat'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-virtualtime-compat'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/litetestintro.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.lite.virtualtime'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('rx-lite-virtualtime'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/outro.js
================================================
}.call(this));
================================================
FILE: src/core/headers/sortingheader.js
================================================
var Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
observableNever = Observable.never,
isEqual = Rx.internals.isEqual,
defaultSubComparer = Rx.helpers.defaultSubComparer;
================================================
FILE: src/core/headers/subintro.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx'], function (Rx, exports) {
return factory(root, exports, Rx);
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/suboutro.js
================================================
return Rx;
}));
================================================
FILE: src/core/headers/testheader.js
================================================
// Defaults
var Observer = Rx.Observer,
Observable = Rx.Observable,
Notification = Rx.Notification,
VirtualTimeScheduler = Rx.VirtualTimeScheduler,
Disposable = Rx.Disposable,
disposableEmpty = Disposable.empty,
disposableCreate = Disposable.create,
CompositeDisposable = Rx.CompositeDisposable,
inherits = Rx.internals.inherits,
defaultComparer = Rx.internals.isEqual;
================================================
FILE: src/core/headers/testintro.js
================================================
;(function (factory) {
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global === 'object' && global);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Because of build optimizers
if (typeof define === 'function' && define.amd) {
define(['./rx.virtualtime', 'exports'], function (Rx, exports) {
root.Rx = factory(root, exports, Rx);
return root.Rx;
});
} else if (typeof module === 'object' && module && module.exports === freeExports) {
module.exports = factory(root, module.exports, require('./rx'));
} else {
root.Rx = factory(root, {}, root.Rx);
}
}.call(this, function (root, exp, Rx, undefined) {
================================================
FILE: src/core/headers/timeheader.js
================================================
// Refernces
var inherits = Rx.internals.inherits,
AbstractObserver = Rx.internals.AbstractObserver,
Observable = Rx.Observable,
observableProto = Observable.prototype,
AnonymousObservable = Rx.AnonymousObservable,
ObservableBase = Rx.ObservableBase,
observableDefer = Observable.defer,
observableEmpty = Observable.empty,
observableNever = Observable.never,
observableThrow = Observable['throw'],
observableFromArray = Observable.fromArray,
defaultScheduler = Rx.Scheduler['default'],
SingleAssignmentDisposable = Rx.SingleAssignmentDisposable,
SerialDisposable = Rx.SerialDisposable,
CompositeDisposable = Rx.CompositeDisposable,
BinaryDisposable = Rx.BinaryDisposable,
RefCountDisposable = Rx.RefCountDisposable,
Subject = Rx.Subject,
addRef = Rx.internals.addRef,
normalizeTime = Rx.Scheduler.normalize,
helpers = Rx.helpers,
isPromise = helpers.isPromise,
isFunction = helpers.isFunction,
isScheduler = Rx.Scheduler.isScheduler,
observableFromPromise = Observable.fromPromise;
================================================
FILE: src/core/headers/virtualtimeheader.js
================================================
// Aliases
var Scheduler = Rx.Scheduler,
ScheduledItem = Rx.internals.ScheduledItem,
SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive,
PriorityQueue = Rx.internals.PriorityQueue,
inherits = Rx.internals.inherits,
defaultSubComparer = Rx.helpers.defaultSubComparer,
notImplemented = Rx.helpers.notImplemented;
================================================
FILE: src/core/internal/bindcallback.js
================================================
var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) {
if (typeof thisArg === 'undefined') { return func; }
switch(argCount) {
case 0:
return function() {
return func.call(thisArg)
};
case 1:
return function(arg) {
return func.call(thisArg, arg);
};
case 2:
return function(value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function() {
return func.apply(thisArg, arguments);
};
};
================================================
FILE: src/core/internal/dontenums.js
================================================
/** Used to determine if values are of the language type Object */
var dontEnums = ['toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'],
dontEnumsLength = dontEnums.length;
================================================
FILE: src/core/internal/errors.js
================================================
var EmptyError = Rx.EmptyError = function() {
this.message = 'Sequence contains no elements.';
Error.call(this);
};
EmptyError.prototype = Object.create(Error.prototype);
EmptyError.prototype.name = 'EmptyError';
var ObjectDisposedError = Rx.ObjectDisposedError = function() {
this.message = 'Object has been disposed';
Error.call(this);
};
ObjectDisposedError.prototype = Object.create(Error.prototype);
ObjectDisposedError.prototype.name = 'ObjectDisposedError';
var ArgumentOutOfRangeError = Rx.ArgumentOutOfRangeError = function () {
this.message = 'Argument out of range';
Error.call(this);
};
ArgumentOutOfRangeError.prototype = Object.create(Error.prototype);
ArgumentOutOfRangeError.prototype.name = 'ArgumentOutOfRangeError';
var NotSupportedError = Rx.NotSupportedError = function (message) {
this.message = message || 'This operation is not supported';
Error.call(this);
};
NotSupportedError.prototype = Object.create(Error.prototype);
NotSupportedError.prototype.name = 'NotSupportedError';
var NotImplementedError = Rx.NotImplementedError = function (message) {
this.message = message || 'This operation is not implemented';
Error.call(this);
};
NotImplementedError.prototype = Object.create(Error.prototype);
NotImplementedError.prototype.name = 'NotImplementedError';
var notImplemented = Rx.helpers.notImplemented = function () {
throw new NotImplementedError();
};
var notSupported = Rx.helpers.notSupported = function () {
throw new NotSupportedError();
};
================================================
FILE: src/core/internal/isequal.js
================================================
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || (function() {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength, key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor === 'function' && objCtor instanceof objCtor &&
typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return (object !== +object) ?
other !== +other :
object === +other;
case regexpTag:
case stringTag:
return object === (other + '');
}
return false;
}
var isObject = Rx.internals.isObject = function(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = (function() {
try {
Object({ 'toString': 0 } + '');
} catch(e) {
return function() { return false; };
}
return function(value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}());
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function(value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome (array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function(othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
var isEqual = Rx.internals.isEqual = function (value, other) {
return baseIsEqual(value, other);
};
================================================
FILE: src/core/internal/map.js
================================================
var Map = root.Map || (function () {
function Map() {
this.size = 0;
this._values = [];
this._keys = [];
}
Map.prototype['delete'] = function (key) {
var i = this._keys.indexOf(key);
if (i === -1) { return false; }
this._values.splice(i, 1);
this._keys.splice(i, 1);
this.size--;
return true;
};
Map.prototype.get = function (key) {
var i = this._keys.indexOf(key);
return i === -1 ? undefined : this._values[i];
};
Map.prototype.set = function (key, value) {
var i = this._keys.indexOf(key);
if (i === -1) {
this._keys.push(key);
this._values.push(value);
this.size++;
} else {
this._values[i] = value;
}
return this;
};
Map.prototype.forEach = function (cb, thisArg) {
for (var i = 0; i < this.size; i++) {
cb.call(thisArg, this._values[i], this._keys[i]);
}
};
return Map;
}());
================================================
FILE: src/core/internal/polyfills.js
================================================
// Utilities
var toString = Object.prototype.toString;
var arrayClass = '[object Array]',
funcClass = '[object Function]',
stringClass = '[object String]';
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k++;
}
};
}
var boxedString = Object('a'),
splitString = boxedString[0] !== 'a' || !(0 in boxedString);
if (!Array.prototype.every) {
Array.prototype.every = function every(fun /*, thisp */) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self && !fun.call(thisp, self[i], i, object)) {
return false;
}
}
return true;
};
}
if (!Array.prototype.map) {
Array.prototype.map = function map(fun /*, thisp*/) {
var object = Object(this),
self = splitString && toString.call(this) === stringClass ?
this.split('') :
object,
length = self.length >>> 0,
result = new Array(length),
thisp = arguments[1];
if (toString.call(fun) !== funcClass) {
throw new TypeError(fun + ' is not a function');
}
for (var i = 0; i < length; i++) {
if (i in self) {
result[i] = fun.call(thisp, self[i], i, object);
}
}
return result;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function (predicate) {
var results = [], item, t = new Object(this);
for (var i = 0, len = t.length >>> 0; i < len; i++) {
item = t[i];
if (i in t && predicate.call(arguments[1], item, i, t)) {
results.push(item);
}
}
return results;
};
}
if (!Array.isArray) {
Array.isArray = function (arg) {
return toString.call(arg) === arrayClass;
};
}
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(searchElement) {
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== Infinity && n !== -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
// Fix for Tessel
if (!Object.prototype.propertyIsEnumerable) {
Object.prototype.propertyIsEnumerable = function (key) {
for (var k in this) { if (k === key) { return true; } }
return false;
};
}
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
if (typeof Object.create !== 'function') {
// Production steps of ECMA-262, Edition 5, 15.2.3.5
// Reference: http://es5.github.io/#x15.2.3.5
Object.create = (function() {
function Temp() {}
var hasOwn = Object.prototype.hasOwnProperty;
return function (O) {
if (typeof O !== 'object') {
throw new TypeError('Object prototype may only be an Object or null');
}
Temp.prototype = O;
var obj = new Temp();
Temp.prototype = null;
if (arguments.length > 1) {
// Object.defineProperties does ToObject on its first argument.
var Properties = Object(arguments[1]);
for (var prop in Properties) {
if (hasOwn.call(Properties, prop)) {
obj[prop] = Properties[prop];
}
}
}
// 5. Return obj
return obj;
};
})();
}
root.Element && root.Element.prototype.attachEvent && !root.Element.prototype.addEventListener && (function () {
function addMethod(name, fn) {
Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = fn;
}
addMethod('addEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
target.attachEvent('on' + type, typeListeners.event = function (e) {
e || (e = root.event);
var documentElement = target.document &&
target.document.documentElement ||
target.documentElement ||
{ scrollLeft: 0, scrollTop: 0 };
e.currentTarget = target;
e.pageX = e.clientX + documentElement.scrollLeft;
e.pageY = e.clientY + documentElement.scrollTop;
e.preventDefault = function () {
e.bubbledKeyCode = e.keyCode;
if (e.ctrlKey) {
try {
e.keyCode = 0;
} catch (e) { }
}
e.defaultPrevented = true;
e.returnValue = false;
e.modified = true;
e.returnValue = false;
};
e.stopImmediatePropagation = function () {
immediatePropagation = false;
e.cancelBubble = true;
};
e.stopPropagation = function () {
e.cancelBubble = true;
};
e.relatedTarget = e.fromElement || null;
e.target = e.srcElement || target;
e.timeStamp = +new Date();
// Normalize key events
switch(e.type) {
case 'keypress':
var c = ('charCode' in e ? e.charCode : e.keyCode);
if (c === 10) {
c = 0;
e.keyCode = 13;
} else if (c === 13 || c === 27) {
c = 0;
} else if (c === 3) {
c = 99;
}
e.charCode = c;
e.keyChar = e.charCode ? String.fromCharCode(e.charCode) : '';
break;
}
var copiedEvent = {};
for (var prop in e) {
copiedEvent[prop] = e[prop];
}
for (var i = 0, typeListenersCache = [].concat(typeListeners), typeListenerCache, immediatePropagation = true; immediatePropagation && (typeListenerCache = typeListenersCache[i]); ++i) {
for (var ii = 0, typeListener; typeListener = typeListeners[ii]; ++ii) {
if (typeListener === typeListenerCache) { typeListener.call(target, copiedEvent); break; }
}
}
});
typeListeners.push(listener);
});
addMethod('removeEventListener', function (type, listener) {
var target = this;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
for (var i = typeListeners.length - 1, typeListener; typeListener = typeListeners[i]; --i) {
if (typeListener === listener) { typeListeners.splice(i, 1); break; }
}
!typeListeners.length &&
typeListeners.event &&
target.detachEvent('on' + type, typeListeners.event);
});
addMethod('dispatchEvent', function (e) {
var target = this;
var type = e.type;
var listeners = target._c1_listeners = target._c1_listeners || {};
var typeListeners = listeners[type] = listeners[type] || [];
try {
return target.fireEvent('on' + type, e);
} catch (err) {
return typeListeners.event && typeListeners.event(e);
}
});
function ready() {
if (ready.interval && document.body) {
ready.interval = clearInterval(ready.interval);
document.dispatchEvent(new CustomEvent('DOMContentLoaded'));
}
}
ready.interval = setInterval(ready, 1);
root.addEventListener('load', ready);
}());
(!root.CustomEvent || typeof root.CustomEvent === 'object') && (function() {
function CustomEvent (type, params) {
var event;
params = params || { bubbles: false, cancelable: false, detail: undefined };
try {
if (document.createEvent) {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
} else if (document.createEventObject) {
event = document.createEventObject();
}
} catch (error) {
event = document.createEvent('Event');
event.initEvent(type, params.bubbles, params.cancelable);
event.detail = params.detail;
}
return event;
}
root.CustomEvent && (CustomEvent.prototype = root.CustomEvent.prototype);
root.CustomEvent = CustomEvent;
}());
================================================
FILE: src/core/internal/priorityqueue.js
================================================
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) {
this.items = new Array(capacity);
this.length = 0;
};
var priorityProto = PriorityQueue.prototype;
priorityProto.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
priorityProto.percolate = function (index) {
if (index >= this.length || index < 0) { return; }
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) { return; }
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
priorityProto.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) { return; }
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
priorityProto.peek = function () { return this.items[0].value; };
priorityProto.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
priorityProto.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
priorityProto.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
priorityProto.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
================================================
FILE: src/core/internal/trycatch.js
================================================
var errorObj = {e: {}};
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
var tryCatch = Rx.internals.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) { throw new TypeError('fn must be a function'); }
return tryCatcherGen(fn);
};
function thrower(e) {
throw e;
}
================================================
FILE: src/core/internal/util.js
================================================
var hasProp = {}.hasOwnProperty,
slice = Array.prototype.slice;
var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};
var addProperties = Rx.internals.addProperties = function (obj) {
for(var sources = [], i = 1, len = arguments.length; i < len; i++) { sources.push(arguments[i]); }
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
// Rx Utils
var addRef = Rx.internals.addRef = function (xs, r) {
return new AnonymousObservable(function (observer) {
return new BinaryDisposable(r.getDisposable(), xs.subscribe(observer));
});
};
function arrayInitialize(count, factory) {
var a = new Array(count);
for (var i = 0; i < count; i++) {
a[i] = factory();
}
return a;
}
================================================
FILE: src/core/joins/activeplan.js
================================================
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this.joinObserverArray = joinObserverArray;
this.onNext = onNext;
this.onCompleted = onCompleted;
this.joinObservers = new Map();
for (var i = 0, len = this.joinObserverArray.length; i < len; i++) {
var joinObserver = this.joinObserverArray[i];
this.joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this.joinObservers.forEach(function (v) { v.queue.shift(); });
};
ActivePlan.prototype.match = function () {
var i, len, hasValues = true;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
if (this.joinObserverArray[i].queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this.joinObserverArray.length; i < len; i++) {
firstValues.push(this.joinObserverArray[i].queue[0]);
this.joinObserverArray[i].queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this.onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this.onNext.apply(this, values);
}
}
};
================================================
FILE: src/core/joins/joinobserver.js
================================================
var JoinObserver = (function (__super__) {
inherits(JoinObserver, __super__);
function JoinObserver(source, onError) {
__super__.call(this);
this.source = source;
this.onError = onError;
this.queue = [];
this.activePlans = [];
this.subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
var JoinObserverPrototype = JoinObserver.prototype;
JoinObserverPrototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this.onError(notification.error);
}
this.queue.push(notification);
var activePlans = this.activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserverPrototype.error = noop;
JoinObserverPrototype.completed = noop;
JoinObserverPrototype.addActivePlan = function (activePlan) {
this.activePlans.push(activePlan);
};
JoinObserverPrototype.subscribe = function () {
this.subscription.setDisposable(this.source.materialize().subscribe(this));
};
JoinObserverPrototype.removeActivePlan = function (activePlan) {
this.activePlans.splice(this.activePlans.indexOf(activePlan), 1);
this.activePlans.length === 0 && this.dispose();
};
JoinObserverPrototype.dispose = function () {
__super__.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this.subscription.dispose();
}
};
return JoinObserver;
} (AbstractObserver));
================================================
FILE: src/core/joins/pattern.js
================================================
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this.patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this.patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
================================================
FILE: src/core/joins/plan.js
================================================
function Plan(expression, selector) {
this.expression = expression;
this.selector = selector;
}
function handleOnError(o) { return function (e) { o.onError(e); }; }
function handleOnNext(self, observer) {
return function onNext () {
var result = tryCatch(self.selector).apply(self, arguments);
if (result === errorObj) { return observer.onError(result.e); }
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [], errHandler = handleOnError(observer);
for (var i = 0, len = this.expression.patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
================================================
FILE: src/core/linq/connectableobservable.js
================================================
var RefCountObservable = (function (__super__) {
inherits(RefCountObservable, __super__);
function RefCountObservable(source) {
this.source = source;
this._count = 0;
this._connectableSubscription = null;
__super__.call(this);
}
RefCountObservable.prototype.subscribeCore = function (o) {
var subscription = this.source.subscribe(o);
++this._count === 1 && (this._connectableSubscription = this.source.connect());
return new RefCountDisposable(this, subscription);
};
function RefCountDisposable(p, s) {
this._p = p;
this._s = s;
this.isDisposed = false;
}
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._s.dispose();
--this._p._count === 0 && this._p._connectableSubscription.dispose();
}
};
return RefCountObservable;
}(ObservableBase));
var ConnectableObservable = Rx.ConnectableObservable = (function (__super__) {
inherits(ConnectableObservable, __super__);
function ConnectableObservable(source, subject) {
this.source = source;
this._connection = null;
this._source = source.asObservable();
this._subject = subject;
__super__.call(this);
}
function ConnectDisposable(parent, subscription) {
this._p = parent;
this._s = subscription;
}
ConnectDisposable.prototype.dispose = function () {
if (this._s) {
this._s.dispose();
this._s = null;
this._p._connection = null;
}
};
ConnectableObservable.prototype.connect = function () {
if (!this._connection) {
if (this._subject.isStopped) {
return disposableEmpty;
}
var subscription = this._source.subscribe(this._subject);
this._connection = new ConnectDisposable(this, subscription);
}
return this._connection;
};
ConnectableObservable.prototype._subscribe = function (o) {
return this._subject.subscribe(o);
};
ConnectableObservable.prototype.refCount = function () {
return new RefCountObservable(this);
};
return ConnectableObservable;
}(Observable));
================================================
FILE: src/core/linq/enumerable/while.js
================================================
var WhileEnumerable = (function(__super__) {
inherits(WhileEnumerable, __super__);
function WhileEnumerable(c, s) {
this.c = c;
this.s = s;
}
WhileEnumerable.prototype[$iterator$] = function () {
var self = this;
return {
next: function () {
return self.c() ?
{ done: false, value: self.s } :
{ done: true, value: void 0 };
}
};
};
return WhileEnumerable;
}(Enumerable));
function enumerableWhile(condition, source) {
return new WhileEnumerable(condition, source);
}
================================================
FILE: src/core/linq/groupedobservable.js
================================================
var UnderlyingObservable = (function (__super__) {
inherits(UnderlyingObservable, __super__);
function UnderlyingObservable(m, u) {
this._m = m;
this._u = u;
__super__.call(this);
}
UnderlyingObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._m.getDisposable(), this._u.subscribe(o));
};
return UnderlyingObservable;
}(ObservableBase));
var GroupedObservable = (function (__super__) {
inherits(GroupedObservable, __super__);
function GroupedObservable(key, underlyingObservable, mergedDisposable) {
__super__.call(this);
this.key = key;
this.underlyingObservable = !mergedDisposable ?
underlyingObservable :
new UnderlyingObservable(mergedDisposable, underlyingObservable);
}
GroupedObservable.prototype._subscribe = function (o) {
return this.underlyingObservable.subscribe(o);
};
return GroupedObservable;
}(Observable));
================================================
FILE: src/core/linq/observable/_extremaby.js
================================================
var ExtremaByObservable = (function (__super__) {
inherits(ExtremaByObservable, __super__);
function ExtremaByObservable(source, k, c) {
this.source = source;
this._k = k;
this._c = c;
__super__.call(this);
}
ExtremaByObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ExtremaByObserver(o, this._k, this._c));
};
return ExtremaByObservable;
}(ObservableBase));
var ExtremaByObserver = (function (__super__) {
inherits(ExtremaByObserver, __super__);
function ExtremaByObserver(o, k, c) {
this._o = o;
this._k = k;
this._c = c;
this._v = null;
this._hv = false;
this._l = [];
__super__.call(this);
}
ExtremaByObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var comparison = 0;
if (!this._hv) {
this._hv = true;
this._v = key;
} else {
comparison = tryCatch(this._c)(key, this._v);
if (comparison === errorObj) { return this._o.onError(comparison.e); }
}
if (comparison > 0) {
this._v = key;
this._l = [];
}
if (comparison >= 0) { this._l.push(x); }
};
ExtremaByObserver.prototype.error = function (e) {
this._o.onError(e);
};
ExtremaByObserver.prototype.completed = function () {
this._o.onNext(this._l);
this._o.onCompleted();
};
return ExtremaByObserver;
}(AbstractObserver));
================================================
FILE: src/core/linq/observable/_findvalue.js
================================================
var FindValueObserver = (function(__super__) {
inherits(FindValueObserver, __super__);
function FindValueObserver(observer, source, callback, yieldIndex) {
this._o = observer;
this._s = source;
this._cb = callback;
this._y = yieldIndex;
this._i = 0;
__super__.call(this);
}
FindValueObserver.prototype.next = function (x) {
var shouldRun = tryCatch(this._cb)(x, this._i, this._s);
if (shouldRun === errorObj) { return this._o.onError(shouldRun.e); }
if (shouldRun) {
this._o.onNext(this._y ? this._i : x);
this._o.onCompleted();
} else {
this._i++;
}
};
FindValueObserver.prototype.error = function (e) {
this._o.onError(e);
};
FindValueObserver.prototype.completed = function () {
this._y && this._o.onNext(-1);
this._o.onCompleted();
};
return FindValueObserver;
}(AbstractObserver));
function findValue (source, predicate, thisArg, yieldIndex) {
var callback = bindCallback(predicate, thisArg, 3);
return new AnonymousObservable(function (o) {
return source.subscribe(new FindValueObserver(o, source, callback, yieldIndex));
}, source);
}
================================================
FILE: src/core/linq/observable/_firstonly.js
================================================
function firstOnly(x) {
if (x.length === 0) { throw new EmptyError(); }
return x[0];
}
================================================
FILE: src/core/linq/observable/_observabletimer.js
================================================
var TimerObservable = (function(__super__) {
inherits(TimerObservable, __super__);
function TimerObservable(dt, s) {
this._dt = dt;
this._s = s;
__super__.call(this);
}
TimerObservable.prototype.subscribeCore = function (o) {
return this._s.scheduleFuture(o, this._dt, scheduleMethod);
};
function scheduleMethod(s, o) {
o.onNext(0);
o.onCompleted();
}
return TimerObservable;
}(ObservableBase));
function _observableTimer(dueTime, scheduler) {
return new TimerObservable(dueTime, scheduler);
}
================================================
FILE: src/core/linq/observable/_observabletimerdateandperiod.js
================================================
function observableTimerDateAndPeriod(dueTime, period, scheduler) {
return new AnonymousObservable(function (observer) {
var d = dueTime, p = normalizeTime(period);
return scheduler.scheduleRecursiveFuture(0, d, function (count, self) {
if (p > 0) {
var now = scheduler.now();
d = new Date(d.getTime() + p);
d.getTime() <= now && (d = new Date(now + p));
}
observer.onNext(count);
self(count + 1, new Date(d));
});
});
}
================================================
FILE: src/core/linq/observable/_observabletimertimespanandperiod.js
================================================
function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) {
return dueTime === period ?
new AnonymousObservable(function (observer) {
return scheduler.schedulePeriodic(0, period, function (count) {
observer.onNext(count);
return count + 1;
});
}) :
observableDefer(function () {
return observableTimerDateAndPeriod(new Date(scheduler.now() + dueTime), period, scheduler);
});
}
================================================
FILE: src/core/linq/observable/amb.js
================================================
function amb(p, c) { return p.amb(c); }
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
Observable.amb = function () {
var acc = observableNever(), items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(items);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
for (var i = 0, len = items.length; i < len; i++) {
acc = amb(acc, items[i]);
}
return acc;
};
================================================
FILE: src/core/linq/observable/ambproto.js
================================================
/**
* Propagates the observable sequence or Promise that reacts first.
* @param {Observable} rightSource Second observable sequence or Promise.
* @returns {Observable} {Observable} An observable sequence that surfaces either of the given sequences, whichever reacted first.
*/
observableProto.amb = function (rightSource) {
var leftSource = this;
return new AnonymousObservable(function (observer) {
var choice,
leftChoice = 'L', rightChoice = 'R',
leftSubscription = new SingleAssignmentDisposable(),
rightSubscription = new SingleAssignmentDisposable();
isPromise(rightSource) && (rightSource = observableFromPromise(rightSource));
function choiceL() {
if (!choice) {
choice = leftChoice;
rightSubscription.dispose();
}
}
function choiceR() {
if (!choice) {
choice = rightChoice;
leftSubscription.dispose();
}
}
var leftSubscribe = observerCreate(
function (left) {
choiceL();
choice === leftChoice && observer.onNext(left);
},
function (e) {
choiceL();
choice === leftChoice && observer.onError(e);
},
function () {
choiceL();
choice === leftChoice && observer.onCompleted();
}
);
var rightSubscribe = observerCreate(
function (right) {
choiceR();
choice === rightChoice && observer.onNext(right);
},
function (e) {
choiceR();
choice === rightChoice && observer.onError(e);
},
function () {
choiceR();
choice === rightChoice && observer.onCompleted();
}
);
leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));
rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));
return new BinaryDisposable(leftSubscription, rightSubscription);
});
};
================================================
FILE: src/core/linq/observable/and.js
================================================
/**
* Creates a pattern that matches when both observable sequences have an available value.
*
* @param right Observable sequence to match with the current sequence.
* @return {Pattern} Pattern object that matches when both observable sequences have an available value.
*/
observableProto.and = function (right) {
return new Pattern([this, right]);
};
================================================
FILE: src/core/linq/observable/asobservable.js
================================================
function asObservable(source) {
return function subscribe(o) { return source.subscribe(o); };
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
observableProto.asObservable = function () {
return new AnonymousObservable(asObservable(this), this);
};
================================================
FILE: src/core/linq/observable/average.js
================================================
var AverageObservable = (function (__super__) {
inherits(AverageObservable, __super__);
function AverageObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
AverageObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new AverageObserver(o, this._fn, this.source));
};
return AverageObservable;
}(ObservableBase));
var AverageObserver = (function(__super__) {
inherits(AverageObserver, __super__);
function AverageObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._c = 0;
this._t = 0;
__super__.call(this);
}
AverageObserver.prototype.next = function (x) {
if(this._fn) {
var r = tryCatch(this._fn)(x, this._c++, this._s);
if (r === errorObj) { return this._o.onError(r.e); }
this._t += r;
} else {
this._c++;
this._t += x;
}
};
AverageObserver.prototype.error = function (e) { this._o.onError(e); };
AverageObserver.prototype.completed = function () {
if (this._c === 0) { return this._o.onError(new EmptyError()); }
this._o.onNext(this._t / this._c);
this._o.onCompleted();
};
return AverageObserver;
}(AbstractObserver));
/**
* Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the average of the sequence of values.
*/
observableProto.average = function (keySelector, thisArg) {
var source = this, fn;
if (isFunction(keySelector)) {
fn = bindCallback(keySelector, thisArg, 3);
}
return new AverageObservable(source, fn);
};
================================================
FILE: src/core/linq/observable/buffer.js
================================================
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers.
* @param {Mixed} bufferOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [bufferClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.buffer = function () {
return this.window.apply(this, arguments)
.flatMap(toArray);
};
================================================
FILE: src/core/linq/observable/bufferwithcount.js
================================================
function toArray(x) { return x.toArray(); }
function notEmpty(x) { return x.length > 0; }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on element count information.
* @param {Number} count Length of each buffer.
* @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithCount = observableProto.bufferCount = function (count, skip) {
typeof skip !== 'number' && (skip = count);
return this.windowWithCount(count, skip)
.flatMap(toArray)
.filter(notEmpty);
};
================================================
FILE: src/core/linq/observable/bufferwithtime.js
================================================
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into zero or more buffers which are produced based on timing information.
* @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers.
* @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTime = observableProto.bufferTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
return this.windowWithTime(timeSpan, timeShiftOrScheduler, scheduler).flatMap(toArray);
};
================================================
FILE: src/core/linq/observable/bufferwithtimeorcount.js
================================================
function toArray(x) { return x.toArray(); }
/**
* Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a buffer.
* @param {Number} count Maximum element count of a buffer.
* @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of buffers.
*/
observableProto.bufferWithTimeOrCount = observableProto.bufferTimeOrCount = function (timeSpan, count, scheduler) {
return this.windowWithTimeOrCount(timeSpan, count, scheduler).flatMap(toArray);
};
================================================
FILE: src/core/linq/observable/case.js
================================================
/**
* Uses selector to determine which source in sources to use.
* @param {Function} selector The function which extracts the value for to test in a case statement.
* @param {Array} sources A object which has keys which correspond to the case statement labels.
* @param {Observable} [elseSource] The observable sequence or Promise that will be run if the sources are not matched. If this is not provided, it defaults to Rx.Observabe.empty with the specified scheduler.
*
* @returns {Observable} An observable sequence which is determined by a case statement.
*/
Observable['case'] = function (selector, sources, defaultSourceOrScheduler) {
return observableDefer(function () {
isPromise(defaultSourceOrScheduler) && (defaultSourceOrScheduler = observableFromPromise(defaultSourceOrScheduler));
defaultSourceOrScheduler || (defaultSourceOrScheduler = observableEmpty());
isScheduler(defaultSourceOrScheduler) && (defaultSourceOrScheduler = observableEmpty(defaultSourceOrScheduler));
var result = sources[selector()];
isPromise(result) && (result = observableFromPromise(result));
return result || defaultSourceOrScheduler;
});
};
================================================
FILE: src/core/linq/observable/catch.js
================================================
/**
* Continues an observable sequence that is terminated by an exception with the next observable sequence.
* @param {Array | Arguments} args Arguments or an array to use as the next sequence if an error occurs.
* @returns {Observable} An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully.
*/
var observableCatch = Observable['catch'] = function () {
var items;
if (Array.isArray(arguments[0])) {
items = arguments[0];
} else {
var len = arguments.length;
items = new Array(len);
for(var i = 0; i < len; i++) { items[i] = arguments[i]; }
}
return enumerableOf(items).catchError();
};
================================================
FILE: src/core/linq/observable/catchproto.js
================================================
var CatchObservable = (function (__super__) {
inherits(CatchObservable, __super__);
function CatchObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
CatchObservable.prototype.subscribeCore = function (o) {
var d1 = new SingleAssignmentDisposable(), subscription = new SerialDisposable();
subscription.setDisposable(d1);
d1.setDisposable(this.source.subscribe(new CatchObserver(o, subscription, this._fn)));
return subscription;
};
return CatchObservable;
}(ObservableBase));
var CatchObserver = (function(__super__) {
inherits(CatchObserver, __super__);
function CatchObserver(o, s, fn) {
this._o = o;
this._s = s;
this._fn = fn;
__super__.call(this);
}
CatchObserver.prototype.next = function (x) { this._o.onNext(x); };
CatchObserver.prototype.completed = function () { return this._o.onCompleted(); };
CatchObserver.prototype.error = function (e) {
var result = tryCatch(this._fn)(e);
if (result === errorObj) { return this._o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
var d = new SingleAssignmentDisposable();
this._s.setDisposable(d);
d.setDisposable(result.subscribe(this._o));
};
return CatchObserver;
}(AbstractObserver));
/**
* Continues an observable sequence that is terminated by an exception with the next observable sequence.
* @param {Mixed} handlerOrSecond Exception handler function that returns an observable sequence given the error that occurred in the first sequence, or a second observable sequence used to produce results when an error occurred in the first sequence.
* @returns {Observable} An observable sequence containing the first sequence's elements, followed by the elements of the handler sequence in case an exception occurred.
*/
observableProto['catch'] = function (handlerOrSecond) {
return isFunction(handlerOrSecond) ? new CatchObservable(this, handlerOrSecond) : observableCatch([this, handlerOrSecond]);
};
================================================
FILE: src/core/linq/observable/combinelatestproto.js
================================================
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element.
* This can be in the form of an argument list of observables or an array.
*
* @example
* 1 - obs = observable.combineLatest(obs1, obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
* 2 - obs = observable.combineLatest([obs1, obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
observableProto.combineLatest = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args[0].unshift(this);
} else {
args.unshift(this);
}
return combineLatest.apply(this, args);
};
================================================
FILE: src/core/linq/observable/concatall.js
================================================
/**
* Concatenates an observable sequence of observable sequences.
* @returns {Observable} An observable sequence that contains the elements of each observed inner sequence, in sequential order.
*/
observableProto.concatAll = function () {
return this.merge(1);
};
================================================
FILE: src/core/linq/observable/concatmap.js
================================================
function concatMap(source, selector, thisArg) {
var selectorFunc = bindCallback(selector, thisArg, 3);
return source.map(function (x, i) {
var result = selectorFunc(x, i, source);
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = observableFrom(result));
return result;
}).concatAll();
}
/**
* One of the Following:
* Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence.
*
* @example
* var res = source.concatMap(function (x) { return Rx.Observable.range(0, x); });
* Or:
* Projects each element of an observable sequence to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
*
* var res = source.concatMap(function (x) { return Rx.Observable.range(0, x); }, function (x, y) { return x + y; });
* Or:
* Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence.
*
* var res = source.concatMap(Rx.Observable.fromArray([1,2,3]));
* @param {Function} selector A transform function to apply to each element or an observable sequence to project each element from the
* source sequence onto which could be either an observable or Promise.
* @param {Function} [resultSelector] A transform function to apply to each element of the intermediate sequence.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.
*/
observableProto.selectConcat = observableProto.concatMap = function (selector, resultSelector, thisArg) {
if (isFunction(selector) && isFunction(resultSelector)) {
return this.concatMap(function (x, i) {
var selectorResult = selector(x, i);
isPromise(selectorResult) && (selectorResult = observableFromPromise(selectorResult));
(isArrayLike(selectorResult) || isIterable(selectorResult)) && (selectorResult = observableFrom(selectorResult));
return selectorResult.map(function (y, i2) {
return resultSelector(x, y, i, i2);
});
});
}
return isFunction(selector) ?
concatMap(this, selector, thisArg) :
concatMap(this, function () { return selector; });
};
================================================
FILE: src/core/linq/observable/concatmapobserver.js
================================================
/**
* Projects each notification of an observable sequence to an observable sequence and concats the resulting observable sequences into one observable sequence.
* @param {Function} onNext A transform function to apply to each element; the second parameter of the function represents the index of the source element.
* @param {Function} onError A transform function to apply when an error occurs in the source sequence.
* @param {Function} onCompleted A transform function to apply when the end of the source sequence is reached.
* @param {Any} [thisArg] An optional "this" to use to invoke each transform.
* @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function corresponding to each notification in the input sequence.
*/
observableProto.concatMapObserver = observableProto.selectConcatObserver = function(onNext, onError, onCompleted, thisArg) {
var source = this,
onNextFunc = bindCallback(onNext, thisArg, 2),
onErrorFunc = bindCallback(onError, thisArg, 1),
onCompletedFunc = bindCallback(onCompleted, thisArg, 0);
return new AnonymousObservable(function (observer) {
var index = 0;
return source.subscribe(
function (x) {
var result;
try {
result = onNextFunc(x, index++);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
},
function (err) {
var result;
try {
result = onErrorFunc(err);
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
},
function () {
var result;
try {
result = onCompletedFunc();
} catch (e) {
observer.onError(e);
return;
}
isPromise(result) && (result = observableFromPromise(result));
observer.onNext(result);
observer.onCompleted();
});
}, this).concatAll();
};
================================================
FILE: src/core/linq/observable/concatproto.js
================================================
/**
* Concatenates all the observable sequences. This takes in either an array or variable arguments to concatenate.
* @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
*/
observableProto.concat = function () {
for(var args = [], i = 0, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
args.unshift(this);
return observableConcat.apply(null, args);
};
================================================
FILE: src/core/linq/observable/count.js
================================================
var CountObservable = (function (__super__) {
inherits(CountObservable, __super__);
function CountObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
CountObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new CountObserver(o, this._fn, this.source));
};
return CountObservable;
}(ObservableBase));
var CountObserver = (function (__super__) {
inherits(CountObserver, __super__);
function CountObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
CountObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
Boolean(result) && (this._c++);
} else {
this._c++;
}
};
CountObserver.prototype.error = function (e) { this._o.onError(e); };
CountObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return CountObserver;
}(AbstractObserver));
/**
* Returns an observable sequence containing a value that represents how many elements in the specified observable sequence satisfy a condition if provided, else the count of items.
* @example
* res = source.count();
* res = source.count(function (x) { return x > 3; });
* @param {Function} [predicate]A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with a number that represents how many elements in the input sequence satisfy the condition in the predicate function if provided, else the count of items in the sequence.
*/
observableProto.count = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new CountObservable(this, fn);
};
================================================
FILE: src/core/linq/observable/create.js
================================================
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @example
* var res = Rx.Observable.create(function (observer) { return function () { } );
* var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } );
* var res = Rx.Observable.create(function (observer) { } );
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
Observable.create = function (subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
================================================
FILE: src/core/linq/observable/debounce.js
================================================
var DebounceObservable = (function (__super__) {
inherits(DebounceObservable, __super__);
function DebounceObservable(source, dt, s) {
isScheduler(s) || (s = defaultScheduler);
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(
this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)),
cancelable);
};
return DebounceObservable;
}(ObservableBase));
var DebounceObserver = (function (__super__) {
inherits(DebounceObserver, __super__);
function DebounceObserver(observer, dueTime, scheduler, cancelable) {
this._o = observer;
this._d = dueTime;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
__super__.call(this);
}
function scheduleFuture(s, state) {
state.self._hv && state.self._id === state.currentId && state.self._o.onNext(state.x);
state.self._hv = false;
}
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id, d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
return DebounceObserver;
}(AbstractObserver));
function debounceWithSelector(source, durationSelector) {
return new AnonymousObservable(function (o) {
var value, hasValue = false, cancelable = new SerialDisposable(), id = 0;
var subscription = source.subscribe(
function (x) {
var throttle = tryCatch(durationSelector)(x);
if (throttle === errorObj) { return o.onError(throttle.e); }
isPromise(throttle) && (throttle = observableFromPromise(throttle));
hasValue = true;
value = x;
id++;
var currentid = id, d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(throttle.subscribe(
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
},
function (e) { o.onError(e); },
function () {
hasValue && id === currentid && o.onNext(value);
hasValue = false;
d.dispose();
}
));
},
function (e) {
cancelable.dispose();
o.onError(e);
hasValue = false;
id++;
},
function () {
cancelable.dispose();
hasValue && o.onNext(value);
o.onCompleted();
hasValue = false;
id++;
}
);
return new BinaryDisposable(subscription, cancelable);
}, source);
}
observableProto.debounce = function () {
if (isFunction (arguments[0])) {
return debounceWithSelector(this, arguments[0]);
} else if (typeof arguments[0] === 'number') {
return new DebounceObservable(this, arguments[0], arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
================================================
FILE: src/core/linq/observable/defaultifempty.js
================================================
var DefaultIfEmptyObserver = (function (__super__) {
inherits(DefaultIfEmptyObserver, __super__);
function DefaultIfEmptyObserver(o, d) {
this._o = o;
this._d = d;
this._f = false;
__super__.call(this);
}
DefaultIfEmptyObserver.prototype.next = function (x) {
this._f = true;
this._o.onNext(x);
};
DefaultIfEmptyObserver.prototype.error = function (e) {
this._o.onError(e);
};
DefaultIfEmptyObserver.prototype.completed = function () {
!this._f && this._o.onNext(this._d);
this._o.onCompleted();
};
return DefaultIfEmptyObserver;
}(AbstractObserver));
/**
* Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty.
*
* var res = obs = xs.defaultIfEmpty();
* 2 - obs = xs.defaultIfEmpty(false);
*
* @memberOf Observable#
* @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null.
* @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself.
*/
observableProto.defaultIfEmpty = function (defaultValue) {
var source = this;
defaultValue === undefined && (defaultValue = null);
return new AnonymousObservable(function (o) {
return source.subscribe(new DefaultIfEmptyObserver(o, defaultValue));
}, source);
};
================================================
FILE: src/core/linq/observable/defer.js
================================================
var Defer = (function(__super__) {
inherits(Defer, __super__);
function Defer(factory) {
this._f = factory;
__super__.call(this);
}
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) { return observableThrow(result.e).subscribe(o);}
isPromise(result) && (result = observableFromPromise(result));
return result.subscribe(o);
};
return Defer;
}(ObservableBase));
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
var observableDefer = Observable.defer = function (observableFactory) {
return new Defer(observableFactory);
};
================================================
FILE: src/core/linq/observable/delay.js
================================================
function observableDelayRelative(source, dueTime, scheduler) {
return new AnonymousObservable(function (o) {
var active = false,
cancelable = new SerialDisposable(),
exception = null,
q = [],
running = false,
subscription;
subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) {
var d, shouldRun;
if (notification.value.kind === 'E') {
q = [];
q.push(notification);
exception = notification.value.error;
shouldRun = !running;
} else {
q.push({ value: notification.value, timestamp: notification.timestamp + dueTime });
shouldRun = !active;
active = true;
}
if (shouldRun) {
if (exception !== null) {
o.onError(exception);
} else {
d = new SingleAssignmentDisposable();
cancelable.setDisposable(d);
d.setDisposable(scheduler.scheduleRecursiveFuture(null, dueTime, function (_, self) {
var e, recurseDueTime, result, shouldRecurse;
if (exception !== null) {
return;
}
running = true;
do {
result = null;
if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) {
result = q.shift().value;
}
if (result !== null) {
result.accept(o);
}
} while (result !== null);
shouldRecurse = false;
recurseDueTime = 0;
if (q.length > 0) {
shouldRecurse = true;
recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now());
} else {
active = false;
}
e = exception;
running = false;
if (e !== null) {
o.onError(e);
} else if (shouldRecurse) {
self(null, recurseDueTime);
}
}));
}
}
});
return new BinaryDisposable(subscription, cancelable);
}, source);
}
function observableDelayAbsolute(source, dueTime, scheduler) {
return observableDefer(function () {
return observableDelayRelative(source, dueTime - scheduler.now(), scheduler);
});
}
function delayWithSelector(source, subscriptionDelay, delayDurationSelector) {
var subDelay, selector;
if (isFunction(subscriptionDelay)) {
selector = subscriptionDelay;
} else {
subDelay = subscriptionDelay;
selector = delayDurationSelector;
}
return new AnonymousObservable(function (o) {
var delays = new CompositeDisposable(), atEnd = false, subscription = new SerialDisposable();
function start() {
subscription.setDisposable(source.subscribe(
function (x) {
var delay = tryCatch(selector)(x);
if (delay === errorObj) { return o.onError(delay.e); }
var d = new SingleAssignmentDisposable();
delays.add(d);
d.setDisposable(delay.subscribe(
function () {
o.onNext(x);
delays.remove(d);
done();
},
function (e) { o.onError(e); },
function () {
o.onNext(x);
delays.remove(d);
done();
}
));
},
function (e) { o.onError(e); },
function () {
atEnd = true;
subscription.dispose();
done();
}
));
}
function done () {
atEnd && delays.length === 0 && o.onCompleted();
}
if (!subDelay) {
start();
} else {
subscription.setDisposable(subDelay.subscribe(start, function (e) { o.onError(e); }, start));
}
return new BinaryDisposable(subscription, delays);
}, source);
}
/**
* Time shifts the observable sequence by dueTime.
* The relative time intervals between the values are preserved.
*
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence.
* @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delay = function () {
var firstArg = arguments[0];
if (typeof firstArg === 'number' || firstArg instanceof Date) {
var dueTime = firstArg, scheduler = arguments[1];
isScheduler(scheduler) || (scheduler = defaultScheduler);
return dueTime instanceof Date ?
observableDelayAbsolute(this, dueTime, scheduler) :
observableDelayRelative(this, dueTime, scheduler);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return delayWithSelector(this, firstArg, arguments[1]);
} else {
throw new Error('Invalid arguments');
}
};
================================================
FILE: src/core/linq/observable/delaysubscription.js
================================================
var DelaySubscription = (function(__super__) {
inherits(DelaySubscription, __super__);
function DelaySubscription(source, dt, s) {
this.source = source;
this._dt = dt;
this._s = s;
__super__.call(this);
}
DelaySubscription.prototype.subscribeCore = function (o) {
var d = new SerialDisposable();
d.setDisposable(this._s.scheduleFuture([this.source, o, d], this._dt, scheduleMethod));
return d;
};
function scheduleMethod(s, state) {
var source = state[0], o = state[1], d = state[2];
d.setDisposable(source.subscribe(o));
}
return DelaySubscription;
}(ObservableBase));
/**
* Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.delaySubscription(5000); // 5s
* 2 - res = source.delaySubscription(5000, Rx.Scheduler.default); // 5 seconds
*
* @param {Number} dueTime Relative or absolute time shift of the subscription.
* @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} Time-shifted sequence.
*/
observableProto.delaySubscription = function (dueTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new DelaySubscription(this, dueTime, scheduler);
};
================================================
FILE: src/core/linq/observable/dematerialize.js
================================================
var DematerializeObservable = (function (__super__) {
inherits(DematerializeObservable, __super__);
function DematerializeObservable(source) {
this.source = source;
__super__.call(this);
}
DematerializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DematerializeObserver(o));
};
return DematerializeObservable;
}(ObservableBase));
var DematerializeObserver = (function (__super__) {
inherits(DematerializeObserver, __super__);
function DematerializeObserver(o) {
this._o = o;
__super__.call(this);
}
DematerializeObserver.prototype.next = function (x) { x.accept(this._o); };
DematerializeObserver.prototype.error = function (e) { this._o.onError(e); };
DematerializeObserver.prototype.completed = function () { this._o.onCompleted(); };
return DematerializeObserver;
}(AbstractObserver));
/**
* Dematerializes the explicit notification values of an observable sequence as implicit notifications.
* @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values.
*/
observableProto.dematerialize = function () {
return new DematerializeObservable(this);
};
================================================
FILE: src/core/linq/observable/distinct.js
================================================
// Swap out for Array.findIndex
function arrayIndexOfComparer(array, item, comparer) {
for (var i = 0, len = array.length; i < len; i++) {
if (comparer(array[i], item)) { return i; }
}
return -1;
}
function HashSet(comparer) {
this.comparer = comparer;
this.set = [];
}
HashSet.prototype.push = function(value) {
var retValue = arrayIndexOfComparer(this.set, value, this.comparer) === -1;
retValue && this.set.push(value);
return retValue;
};
var DistinctObservable = (function (__super__) {
inherits(DistinctObservable, __super__);
function DistinctObservable(source, keyFn, cmpFn) {
this.source = source;
this._keyFn = keyFn;
this._cmpFn = cmpFn;
__super__.call(this);
}
DistinctObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctObserver(o, this._keyFn, this._cmpFn));
};
return DistinctObservable;
}(ObservableBase));
var DistinctObserver = (function (__super__) {
inherits(DistinctObserver, __super__);
function DistinctObserver(o, keyFn, cmpFn) {
this._o = o;
this._keyFn = keyFn;
this._h = new HashSet(cmpFn);
__super__.call(this);
}
DistinctObserver.prototype.next = function (x) {
var key = x;
if (isFunction(this._keyFn)) {
key = tryCatch(this._keyFn)(x);
if (key === errorObj) { return this._o.onError(key.e); }
}
this._h.push(key) && this._o.onNext(x);
};
DistinctObserver.prototype.error = function (e) { this._o.onError(e); };
DistinctObserver.prototype.completed = function () { this._o.onCompleted(); };
return DistinctObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer.
* Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large.
*
* @example
* var res = obs = xs.distinct();
* 2 - obs = xs.distinct(function (x) { return x.id; });
* 2 - obs = xs.distinct(function (x) { return x.id; }, function (a,b) { return a === b; });
* @param {Function} [keySelector] A function to compute the comparison key for each element.
* @param {Function} [comparer] Used to compare items in the collection.
* @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence.
*/
observableProto.distinct = function (keySelector, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctObservable(this, keySelector, comparer);
};
================================================
FILE: src/core/linq/observable/dowhile.js
================================================
/**
* Repeats source as long as condition holds emulating a do while loop.
*
* @param {Function} condition The condition which determines if the source will be repeated.
* @param {Observable} source The observable sequence that will be run if the condition function returns true.
* @returns {Observable} An observable sequence which is repeated as long as the condition holds.
*/
observableProto.doWhile = function (condition) {
return observableConcat([this, observableWhileDo(condition, this)]);
};
================================================
FILE: src/core/linq/observable/elementat.js
================================================
var ElementAtObservable = (function (__super__) {
inherits(ElementAtObservable, __super__);
function ElementAtObservable(source, i, d) {
this.source = source;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ElementAtObserver(o, this._i, this._d));
};
return ElementAtObservable;
}(ObservableBase));
var ElementAtObserver = (function (__super__) {
inherits(ElementAtObserver, __super__);
function ElementAtObserver(o, i, d) {
this._o = o;
this._i = i;
this._d = d;
__super__.call(this);
}
ElementAtObserver.prototype.next = function (x) {
if (this._i-- === 0) {
this._o.onNext(x);
this._o.onCompleted();
}
};
ElementAtObserver.prototype.error = function (e) { this._o.onError(e); };
ElementAtObserver.prototype.completed = function () {
if (this._d === undefined) {
this._o.onError(new ArgumentOutOfRangeError());
} else {
this._o.onNext(this._d);
this._o.onCompleted();
}
};
return ElementAtObserver;
}(AbstractObserver));
/**
* Returns the element at a specified index in a sequence or default value if not found.
* @param {Number} index The zero-based index of the element to retrieve.
* @param {Any} [defaultValue] The default value to use if elementAt does not find a value.
* @returns {Observable} An observable sequence that produces the element at the specified position in the source sequence.
*/
observableProto.elementAt = function (index, defaultValue) {
if (index < 0) { throw new ArgumentOutOfRangeError(); }
return new ElementAtObservable(this, index, defaultValue);
};
================================================
FILE: src/core/linq/observable/every.js
================================================
var EveryObservable = (function (__super__) {
inherits(EveryObservable, __super__);
function EveryObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
EveryObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new EveryObserver(o, this._fn, this.source));
};
return EveryObservable;
}(ObservableBase));
var EveryObserver = (function (__super__) {
inherits(EveryObserver, __super__);
function EveryObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
EveryObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (!Boolean(result)) {
this._o.onNext(false);
this._o.onCompleted();
}
};
EveryObserver.prototype.error = function (e) { this._o.onError(e); };
EveryObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return EveryObserver;
}(AbstractObserver));
/**
* Determines whether all elements of an observable sequence satisfy a condition.
* @param {Function} [predicate] A function to test each element for a condition.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element determining whether all elements in the source sequence pass the test in the specified predicate.
*/
observableProto.every = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new EveryObservable(this, fn);
};
================================================
FILE: src/core/linq/observable/expand.js
================================================
var ExpandObservable = (function(__super__) {
inherits(ExpandObservable, __super__);
function ExpandObservable(source, fn, scheduler) {
this.source = source;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleRecursive(args, recurse) {
var state = args[0], self = args[1];
var work;
if (state.q.length > 0) {
work = state.q.shift();
} else {
state.isAcquired = false;
return;
}
var m1 = new SingleAssignmentDisposable();
state.d.add(m1);
m1.setDisposable(work.subscribe(new ExpandObserver(state, self, m1)));
recurse([state, self]);
}
ExpandObservable.prototype._ensureActive = function (state) {
var isOwner = false;
if (state.q.length > 0) {
isOwner = !state.isAcquired;
state.isAcquired = true;
}
isOwner && state.m.setDisposable(this._scheduler.scheduleRecursive([state, this], scheduleRecursive));
};
ExpandObservable.prototype.subscribeCore = function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
state = {
q: [],
m: m,
d: d,
activeCount: 0,
isAcquired: false,
o: o
};
state.q.push(this.source);
state.activeCount++;
this._ensureActive(state);
return d;
};
return ExpandObservable;
}(ObservableBase));
var ExpandObserver = (function(__super__) {
inherits(ExpandObserver, __super__);
function ExpandObserver(state, parent, m1) {
this._s = state;
this._p = parent;
this._m1 = m1;
__super__.call(this);
}
ExpandObserver.prototype.next = function (x) {
this._s.o.onNext(x);
var result = tryCatch(this._p._fn)(x);
if (result === errorObj) { return this._s.o.onError(result.e); }
this._s.q.push(result);
this._s.activeCount++;
this._p._ensureActive(this._s);
};
ExpandObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ExpandObserver.prototype.completed = function () {
this._s.d.remove(this._m1);
this._s.activeCount--;
this._s.activeCount === 0 && this._s.o.onCompleted();
};
return ExpandObserver;
}(AbstractObserver));
/**
* Expands an observable sequence by recursively invoking selector.
*
* @param {Function} selector Selector function to invoke for each produced element, resulting in another sequence to which the selector will be invoked recursively again.
* @param {Scheduler} [scheduler] Scheduler on which to perform the expansion. If not provided, this defaults to the current thread scheduler.
* @returns {Observable} An observable sequence containing all the elements produced by the recursive expansion.
*/
observableProto.expand = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new ExpandObservable(this, selector, scheduler);
};
================================================
FILE: src/core/linq/observable/find.js
================================================
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the first element that matches the conditions defined by the specified predicate, if found; otherwise, undefined.
*/
observableProto.find = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, false);
};
================================================
FILE: src/core/linq/observable/findindex.js
================================================
/**
* Searches for an element that matches the conditions defined by the specified predicate, and returns
* an Observable sequence with the zero-based index of the first occurrence within the entire Observable sequence.
* @param {Function} predicate The predicate that defines the conditions of the element to search for.
* @param {Any} [thisArg] Object to use as `this` when executing the predicate.
* @returns {Observable} An Observable sequence with the zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
*/
observableProto.findIndex = function (predicate, thisArg) {
return findValue(this, predicate, thisArg, true);
};
================================================
FILE: src/core/linq/observable/first.js
================================================
var FirstObservable = (function (__super__) {
inherits(FirstObservable, __super__);
function FirstObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
FirstObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FirstObserver(o, this._obj, this.source));
};
return FirstObservable;
}(ObservableBase));
var FirstObserver = (function(__super__) {
inherits(FirstObserver, __super__);
function FirstObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
__super__.call(this);
}
FirstObserver.prototype.next = function (x) {
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
if (Boolean(res)) {
this._o.onNext(x);
this._o.onCompleted();
}
} else if (!this._obj.predicate) {
this._o.onNext(x);
this._o.onCompleted();
}
};
FirstObserver.prototype.error = function (e) { this._o.onError(e); };
FirstObserver.prototype.completed = function () {
if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return FirstObserver;
}(AbstractObserver));
/**
* Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence.
* @returns {Observable} Sequence containing the first element in the observable sequence that satisfies the condition in the predicate if provided, else the first item in the sequence.
*/
observableProto.first = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new FirstObservable(this, obj);
};
================================================
FILE: src/core/linq/observable/for.js
================================================
/**
* Concatenates the observable sequences obtained by running the specified result selector for each element in source.
* There is an alias for this method called 'forIn' for browsers = this._n && comparer(x, this._elem)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
IncludesObserver.prototype.error = function (e) { this._o.onError(e); };
IncludesObserver.prototype.completed = function () { this._o.onNext(false); this._o.onCompleted(); };
return IncludesObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence includes a specified element with an optional equality comparer.
* @param searchElement The value to locate in the source sequence.
* @param {Number} [fromIndex] An equality comparer to compare elements.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence includes an element that has the specified value from the given index.
*/
observableProto.includes = function (searchElement, fromIndex) {
return new IncludesObservable(this, searchElement, fromIndex);
};
================================================
FILE: src/core/linq/observable/indexof.js
================================================
var IndexOfObservable = (function (__super__) {
inherits(IndexOfObservable, __super__);
function IndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
IndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new IndexOfObserver(o, this._e, this._n));
};
return IndexOfObservable;
}(ObservableBase));
var IndexOfObserver = (function (__super__) {
inherits(IndexOfObserver, __super__);
function IndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._i = 0;
__super__.call(this);
}
IndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._o.onNext(this._i);
this._o.onCompleted();
}
this._i++;
};
IndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
IndexOfObserver.prototype.completed = function () { this._o.onNext(-1); this._o.onCompleted(); };
return IndexOfObserver;
}(AbstractObserver));
/**
* Returns the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the first index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.indexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new IndexOfObservable(this, searchElement, n);
};
================================================
FILE: src/core/linq/observable/interval.js
================================================
/**
* Returns an observable sequence that produces a value after each period.
*
* @example
* 1 - res = Rx.Observable.interval(1000);
* 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout);
*
* @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds).
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used.
* @returns {Observable} An observable sequence that produces a value after each period.
*/
var observableinterval = Observable.interval = function (period, scheduler) {
return observableTimerTimeSpanAndPeriod(period, period, isScheduler(scheduler) ? scheduler : defaultScheduler);
};
================================================
FILE: src/core/linq/observable/isempty.js
================================================
var IsEmptyObservable = (function (__super__) {
inherits(IsEmptyObservable, __super__);
function IsEmptyObservable(source) {
this.source = source;
__super__.call(this);
}
IsEmptyObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new IsEmptyObserver(o));
};
return IsEmptyObservable;
}(ObservableBase));
var IsEmptyObserver = (function(__super__) {
inherits(IsEmptyObserver, __super__);
function IsEmptyObserver(o) {
this._o = o;
__super__.call(this);
}
IsEmptyObserver.prototype.next = function () {
this._o.onNext(false);
this._o.onCompleted();
};
IsEmptyObserver.prototype.error = function (e) { this._o.onError(e); };
IsEmptyObserver.prototype.completed = function () {
this._o.onNext(true);
this._o.onCompleted();
};
return IsEmptyObserver;
}(AbstractObserver));
/**
* Determines whether an observable sequence is empty.
* @returns {Observable} An observable sequence containing a single element determining whether the source sequence is empty.
*/
observableProto.isEmpty = function () {
return new IsEmptyObservable(this);
};
================================================
FILE: src/core/linq/observable/join.js
================================================
/**
* Correlates the elements of two sequences based on overlapping durations.
*
* @param {Observable} right The right observable sequence to join elements for.
* @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap.
* @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap.
* @param {Function} resultSelector A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences. The parameters passed to the function correspond with the elements from the left and right source sequences for which overlap occurs.
* @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration.
*/
observableProto.join = function (right, leftDurationSelector, rightDurationSelector, resultSelector) {
var left = this;
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var leftDone = false, rightDone = false;
var leftId = 0, rightId = 0;
var leftMap = new Map(), rightMap = new Map();
var handleError = function (e) { o.onError(e); };
group.add(left.subscribe(
function (value) {
var id = leftId++, md = new SingleAssignmentDisposable();
leftMap.set(id, value);
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
leftMap['delete'](id) && leftMap.size === 0 && leftDone && o.onCompleted();
group.remove(md);
}));
rightMap.forEach(function (v) {
var result = tryCatch(resultSelector)(value, v);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
leftDone = true;
(rightDone || leftMap.size === 0) && o.onCompleted();
})
);
group.add(right.subscribe(
function (value) {
var id = rightId++, md = new SingleAssignmentDisposable();
rightMap.set(id, value);
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) { return o.onError(duration.e); }
md.setDisposable(duration.take(1).subscribe(
noop,
handleError,
function () {
rightMap['delete'](id) && rightMap.size === 0 && rightDone && o.onCompleted();
group.remove(md);
}));
leftMap.forEach(function (v) {
var result = tryCatch(resultSelector)(v, value);
if (result === errorObj) { return o.onError(result.e); }
o.onNext(result);
});
},
handleError,
function () {
rightDone = true;
(leftDone || rightMap.size === 0) && o.onCompleted();
})
);
return group;
}, left);
};
================================================
FILE: src/core/linq/observable/jortsort.js
================================================
/**
* jortSort checks if your inputs are sorted. Note that this is only for a sequence with an end.
* See http://jort.technology/ for full details.
* @returns {Observable} An observable which has a single value of true if sorted, else false.
*/
observableProto.jortSort = function () {
return this.jortSortUntil(observableNever());
};
================================================
FILE: src/core/linq/observable/jortsortuntil.js
================================================
/**
* jortSort checks if your inputs are sorted until another Observable sequence fires.
* See http://jort.technology/ for full details.
* @returns {Observable} An observable which has a single value of true if sorted, else false.
*/
observableProto.jortSortUntil = function (other) {
var source = this;
return new AnonymousObservable(function (observer) {
var arr = [];
return source.takeUntil(other).subscribe(
arr.push.bind(arr),
observer.onError.bind(observer),
function () {
var sorted = arr.slice(0).sort(defaultSubComparer);
observer.onNext(isEqual(arr, sorted));
observer.onCompleted();
});
}, source);
};
================================================
FILE: src/core/linq/observable/last.js
================================================
var LastObservable = (function (__super__) {
inherits(LastObservable, __super__);
function LastObservable(source, obj) {
this.source = source;
this._obj = obj;
__super__.call(this);
}
LastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new LastObserver(o, this._obj, this.source));
};
return LastObservable;
}(ObservableBase));
var LastObserver = (function(__super__) {
inherits(LastObserver, __super__);
function LastObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
LastObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
this._hv = true;
this._v = x;
}
};
LastObserver.prototype.error = function (e) { this._o.onError(e); };
LastObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return LastObserver;
}(AbstractObserver));
/**
* Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element.
* @returns {Observable} Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.last = function () {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new LastObservable(this, obj);
};
================================================
FILE: src/core/linq/observable/lastindexof.js
================================================
var LastIndexOfObservable = (function (__super__) {
inherits(LastIndexOfObservable, __super__);
function LastIndexOfObservable(source, e, n) {
this.source = source;
this._e = e;
this._n = n;
__super__.call(this);
}
LastIndexOfObservable.prototype.subscribeCore = function (o) {
if (this._n < 0) {
o.onNext(-1);
o.onCompleted();
return disposableEmpty;
}
return this.source.subscribe(new LastIndexOfObserver(o, this._e, this._n));
};
return LastIndexOfObservable;
}(ObservableBase));
var LastIndexOfObserver = (function (__super__) {
inherits(LastIndexOfObserver, __super__);
function LastIndexOfObserver(o, e, n) {
this._o = o;
this._e = e;
this._n = n;
this._v = 0;
this._hv = false;
this._i = 0;
__super__.call(this);
}
LastIndexOfObserver.prototype.next = function (x) {
if (this._i >= this._n && x === this._e) {
this._hv = true;
this._v = this._i;
}
this._i++;
};
LastIndexOfObserver.prototype.error = function (e) { this._o.onError(e); };
LastIndexOfObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
} else {
this._o.onNext(-1);
}
this._o.onCompleted();
};
return LastIndexOfObserver;
}(AbstractObserver));
/**
* Returns the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
* @param {Any} searchElement Element to locate in the array.
* @param {Number} [fromIndex] The index to start the search. If not specified, defaults to 0.
* @returns {Observable} And observable sequence containing the last index at which a given element can be found in the observable sequence, or -1 if it is not present.
*/
observableProto.lastIndexOf = function(searchElement, fromIndex) {
var n = +fromIndex || 0;
Math.abs(n) === Infinity && (n = 0);
return new LastIndexOfObservable(this, searchElement, n);
};
================================================
FILE: src/core/linq/observable/let.js
================================================
/**
* Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions.
* This operator allows for a fluent style of writing queries that use the same sequence multiple times.
*
* @param {Function} selector Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
observableProto.letBind = observableProto['let'] = function (func) {
return func(this);
};
================================================
FILE: src/core/linq/observable/manyselect.js
================================================
/**
* Comonadic bind operator.
* @param {Function} selector A transform function to apply to each element.
* @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler.
* @returns {Observable} An observable sequence which results from the comonadic bind operation.
*/
observableProto.manySelect = observableProto.extend = function (selector, scheduler) {
isScheduler(scheduler) || (scheduler = Rx.Scheduler.immediate);
var source = this;
return observableDefer(function () {
var chain;
return source
.map(function (x) {
var curr = new ChainObservable(x);
chain && chain.onNext(x);
chain = curr;
return curr;
})
.tap(
noop,
function (e) { chain && chain.onError(e); },
function () { chain && chain.onCompleted(); }
)
.observeOn(scheduler)
.map(selector);
}, source);
};
var ChainObservable = (function (__super__) {
inherits(ChainObservable, __super__);
function ChainObservable(head) {
__super__.call(this);
this.head = head;
this.tail = new AsyncSubject();
}
addProperties(ChainObservable.prototype, Observer, {
_subscribe: function (o) {
var g = new CompositeDisposable();
g.add(currentThreadScheduler.schedule(this, function (_, self) {
o.onNext(self.head);
g.add(self.tail.mergeAll().subscribe(o));
}));
return g;
},
onCompleted: function () {
this.onNext(Observable.empty());
},
onError: function (e) {
this.onNext(Observable['throw'](e));
},
onNext: function (v) {
this.tail.onNext(v);
this.tail.onCompleted();
}
});
return ChainObservable;
}(Observable));
================================================
FILE: src/core/linq/observable/materialize.js
================================================
var MaterializeObservable = (function (__super__) {
inherits(MaterializeObservable, __super__);
function MaterializeObservable(source, fn) {
this.source = source;
__super__.call(this);
}
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
return MaterializeObservable;
}(ObservableBase));
var MaterializeObserver = (function (__super__) {
inherits(MaterializeObserver, __super__);
function MaterializeObserver(o) {
this._o = o;
__super__.call(this);
}
MaterializeObserver.prototype.next = function (x) { this._o.onNext(notificationCreateOnNext(x)) };
MaterializeObserver.prototype.error = function (e) { this._o.onNext(notificationCreateOnError(e)); this._o.onCompleted(); };
MaterializeObserver.prototype.completed = function () { this._o.onNext(notificationCreateOnCompleted()); this._o.onCompleted(); };
return MaterializeObserver;
}(AbstractObserver));
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
observableProto.materialize = function () {
return new MaterializeObservable(this);
};
================================================
FILE: src/core/linq/observable/max.js
================================================
/**
* Returns the maximum value in an observable sequence according to the specified comparer.
* @example
* var res = source.max();
* var res = source.max(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the maximum element in the source sequence.
*/
observableProto.max = function (comparer) {
return this.maxBy(identity, comparer).map(firstOnly);
};
================================================
FILE: src/core/linq/observable/maxby.js
================================================
/**
* Returns the elements in an observable sequence with the maximum key value according to the specified comparer.
* @example
* var res = source.maxBy(function (x) { return x.value; });
* var res = source.maxBy(function (x) { return x.value; }, function (x, y) { return x - y;; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a maximum key value.
*/
observableProto.maxBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, comparer);
};
================================================
FILE: src/core/linq/observable/merge.js
================================================
/**
* Merges all the observable sequences into a single observable sequence.
* The scheduler is optional and if not specified, the immediate scheduler is used.
* @returns {Observable} The observable sequence that merges the elements of the observable sequences.
*/
var observableMerge = Observable.merge = function () {
var scheduler, sources = [], i, len = arguments.length;
if (!arguments[0]) {
scheduler = immediateScheduler;
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else if (isScheduler(arguments[0])) {
scheduler = arguments[0];
for(i = 1; i < len; i++) { sources.push(arguments[i]); }
} else {
scheduler = immediateScheduler;
for(i = 0; i < len; i++) { sources.push(arguments[i]); }
}
if (Array.isArray(sources[0])) {
sources = sources[0];
}
return observableOf(scheduler, sources).mergeAll();
};
================================================
FILE: src/core/linq/observable/mergedelayerror.js
================================================
var CompositeError = Rx.CompositeError = function(errors) {
this.innerErrors = errors;
this.message = 'This contains multiple errors. Check the innerErrors';
Error.call(this);
};
CompositeError.prototype = Object.create(Error.prototype);
CompositeError.prototype.name = 'CompositeError';
var MergeDelayErrorObservable = (function(__super__) {
inherits(MergeDelayErrorObservable, __super__);
function MergeDelayErrorObservable(source) {
this.source = source;
__super__.call(this);
}
MergeDelayErrorObservable.prototype.subscribeCore = function (o) {
var group = new CompositeDisposable(),
m = new SingleAssignmentDisposable(),
state = { isStopped: false, errors: [], o: o };
group.add(m);
m.setDisposable(this.source.subscribe(new MergeDelayErrorObserver(group, state)));
return group;
};
return MergeDelayErrorObservable;
}(ObservableBase));
var MergeDelayErrorObserver = (function(__super__) {
inherits(MergeDelayErrorObserver, __super__);
function MergeDelayErrorObserver(group, state) {
this._group = group;
this._state = state;
__super__.call(this);
}
function setCompletion(o, errors) {
if (errors.length === 0) {
o.onCompleted();
} else if (errors.length === 1) {
o.onError(errors[0]);
} else {
o.onError(new CompositeError(errors));
}
}
MergeDelayErrorObserver.prototype.next = function (x) {
var inner = new SingleAssignmentDisposable();
this._group.add(inner);
// Check for promises support
isPromise(x) && (x = observableFromPromise(x));
inner.setDisposable(x.subscribe(new InnerObserver(inner, this._group, this._state)));
};
MergeDelayErrorObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
MergeDelayErrorObserver.prototype.completed = function () {
this._state.isStopped = true;
this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
inherits(InnerObserver, __super__);
function InnerObserver(inner, group, state) {
this._inner = inner;
this._group = group;
this._state = state;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._state.o.onNext(x); };
InnerObserver.prototype.error = function (e) {
this._state.errors.push(e);
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
InnerObserver.prototype.completed = function () {
this._group.remove(this._inner);
this._state.isStopped && this._group.length === 1 && setCompletion(this._state.o, this._state.errors);
};
return MergeDelayErrorObserver;
}(AbstractObserver));
/**
* Flattens an Observable that emits Observables into one Observable, in a way that allows an Observer to
* receive all successfully emitted items from all of the source Observables without being interrupted by
* an error notification from one of them.
*
* This behaves like Observable.prototype.mergeAll except that if any of the merged Observables notify of an
* error via the Observer's onError, mergeDelayError will refrain from propagating that
* error notification until all of the merged Observables have finished emitting items.
* @param {Array | Arguments} args Arguments or an array to merge.
* @returns {Observable} an Observable that emits all of the items emitted by the Observables emitted by the Observable
*/
Observable.mergeDelayError = function() {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
var len = arguments.length;
args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
}
var source = observableOf(null, args);
return new MergeDelayErrorObservable(source);
};
================================================
FILE: src/core/linq/observable/min.js
================================================
/**
* Returns the minimum element in an observable sequence according to the optional comparer else a default greater than less than check.
* @example
* var res = source.min();
* var res = source.min(function (x, y) { return x.value - y.value; });
* @param {Function} [comparer] Comparer used to compare elements.
* @returns {Observable} An observable sequence containing a single element with the minimum element in the source sequence.
*/
observableProto.min = function (comparer) {
return this.minBy(identity, comparer).map(firstOnly);
};
================================================
FILE: src/core/linq/observable/minby.js
================================================
/**
* Returns the elements in an observable sequence with the minimum key value according to the specified comparer.
* @example
* var res = source.minBy(function (x) { return x.value; });
* var res = source.minBy(function (x) { return x.value; }, function (x, y) { return x - y; });
* @param {Function} keySelector Key selector function.
* @param {Function} [comparer] Comparer used to compare key values.
* @returns {Observable} An observable sequence containing a list of zero or more elements that have a minimum key value.
*/
observableProto.minBy = function (keySelector, comparer) {
comparer || (comparer = defaultSubComparer);
return new ExtremaByObservable(this, keySelector, function (x, y) { return comparer(x, y) * -1; });
};
================================================
FILE: src/core/linq/observable/multicast.js
================================================
var MulticastObservable = (function (__super__) {
inherits(MulticastObservable, __super__);
function MulticastObservable(source, fn1, fn2) {
this.source = source;
this._fn1 = fn1;
this._fn2 = fn2;
__super__.call(this);
}
MulticastObservable.prototype.subscribeCore = function (o) {
var connectable = this.source.multicast(this._fn1());
return new BinaryDisposable(this._fn2(connectable).subscribe(o), connectable.connect());
};
return MulticastObservable;
}(ObservableBase));
/**
* Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
* subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
* invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
*
* @example
* 1 - res = source.multicast(observable);
* 2 - res = source.multicast(function () { return new Subject(); }, function (x) { return x; });
*
* @param {Function|Subject} subjectOrSubjectSelector
* Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
* Or:
* Subject to push source elements into.
*
* @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if 0) {
var v = qr.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (doner) {
o.onNext(false);
o.onCompleted();
} else {
ql.push(x);
}
}, function(e) { o.onError(e); }, function () {
donel = true;
if (ql.length === 0) {
if (qr.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (doner) {
o.onNext(true);
o.onCompleted();
}
}
});
(isArrayLike(second) || isIterable(second)) && (second = observableFrom(second));
isPromise(second) && (second = observableFromPromise(second));
var subscription2 = second.subscribe(function (x) {
if (ql.length > 0) {
var v = ql.shift();
var equal = tryCatch(comparer)(v, x);
if (equal === errorObj) { return o.onError(equal.e); }
if (!equal) {
o.onNext(false);
o.onCompleted();
}
} else if (donel) {
o.onNext(false);
o.onCompleted();
} else {
qr.push(x);
}
}, function(e) { o.onError(e); }, function () {
doner = true;
if (qr.length === 0) {
if (ql.length > 0) {
o.onNext(false);
o.onCompleted();
} else if (donel) {
o.onNext(true);
o.onCompleted();
}
}
});
return new BinaryDisposable(subscription1, subscription2);
}, first);
};
================================================
FILE: src/core/linq/observable/share.js
================================================
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence.
* This operator is a specialization of publish which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
*/
observableProto.share = function () {
return this.publish().refCount();
};
================================================
FILE: src/core/linq/observable/sharereplay.js
================================================
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.
* This operator is a specialization of replay which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
*
* @example
* var res = source.shareReplay(3);
* var res = source.shareReplay(3, 500);
* var res = source.shareReplay(3, 500, scheduler);
*
* @param bufferSize [Optional] Maximum element count of the replay buffer.
* @param window [Optional] Maximum time length of the replay buffer.
* @param scheduler [Optional] Scheduler where connected observers within the selector function will be invoked on.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
*/
observableProto.shareReplay = function (bufferSize, windowSize, scheduler) {
return this.replay(null, bufferSize, windowSize, scheduler).refCount();
};
================================================
FILE: src/core/linq/observable/sharevalue.js
================================================
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence and starts with an initialValue.
* This operator is a specialization of publishValue which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.
* @param {Mixed} initialValue Initial value received by observers upon subscription.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence.
*/
observableProto.shareValue = function (initialValue) {
return this.publishValue(initialValue).refCount();
};
================================================
FILE: src/core/linq/observable/single.js
================================================
var SingleObserver = (function(__super__) {
inherits(SingleObserver, __super__);
function SingleObserver(o, obj, s) {
this._o = o;
this._obj = obj;
this._s = s;
this._i = 0;
this._hv = false;
this._v = null;
__super__.call(this);
}
SingleObserver.prototype.next = function (x) {
var shouldYield = false;
if (this._obj.predicate) {
var res = tryCatch(this._obj.predicate)(x, this._i++, this._s);
if (res === errorObj) { return this._o.onError(res.e); }
Boolean(res) && (shouldYield = true);
} else if (!this._obj.predicate) {
shouldYield = true;
}
if (shouldYield) {
if (this._hv) {
return this._o.onError(new Error('Sequence contains more than one matching element'));
}
this._hv = true;
this._v = x;
}
};
SingleObserver.prototype.error = function (e) { this._o.onError(e); };
SingleObserver.prototype.completed = function () {
if (this._hv) {
this._o.onNext(this._v);
this._o.onCompleted();
}
else if (this._obj.defaultValue === undefined) {
this._o.onError(new EmptyError());
} else {
this._o.onNext(this._obj.defaultValue);
this._o.onCompleted();
}
};
return SingleObserver;
}(AbstractObserver));
/**
* Returns the only element of an observable sequence that satisfies the condition in the optional predicate, and reports an exception if there is not exactly one element in the observable sequence.
* @returns {Observable} Sequence containing the single element in the observable sequence that satisfies the condition in the predicate.
*/
observableProto.single = function (predicate, thisArg) {
var obj = {}, source = this;
if (typeof arguments[0] === 'object') {
obj = arguments[0];
} else {
obj = {
predicate: arguments[0],
thisArg: arguments[1],
defaultValue: arguments[2]
};
}
if (isFunction (obj.predicate)) {
var fn = obj.predicate;
obj.predicate = bindCallback(fn, obj.thisArg, 3);
}
return new AnonymousObservable(function (o) {
return source.subscribe(new SingleObserver(o, obj, source));
}, source);
};
================================================
FILE: src/core/linq/observable/singleinstance.js
================================================
/**
* Returns an observable sequence that shares a single subscription to the underlying sequence. This observable sequence
* can be resubscribed to, even if all prior subscriptions have ended. (unlike `.publish().refCount()`)
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source.
*/
observableProto.singleInstance = function() {
var source = this, hasObservable = false, observable;
function getObservable() {
if (!hasObservable) {
hasObservable = true;
observable = source['finally'](function() { hasObservable = false; }).publish().refCount();
}
return observable;
}
return new AnonymousObservable(function(o) {
return getObservable().subscribe(o);
});
};
================================================
FILE: src/core/linq/observable/skiplast.js
================================================
var SkipLastObservable = (function (__super__) {
inherits(SkipLastObservable, __super__);
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
__super__.call(this);
}
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
return SkipLastObservable;
}(ObservableBase));
var SkipLastObserver = (function (__super__) {
inherits(SkipLastObserver, __super__);
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipLastObserver.prototype.completed = function () {
this._o.onCompleted();
};
return SkipLastObserver;
}(AbstractObserver));
/**
* Bypasses a specified number of elements at the end of an observable sequence.
* @description
* This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are
* received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed.
* @param count Number of elements to bypass at the end of the source sequence.
* @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end.
*/
observableProto.skipLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipLastObservable(this, count);
};
================================================
FILE: src/core/linq/observable/skiplastwithtime.js
================================================
var SkipLastWithTimeObservable = (function (__super__) {
inherits(SkipLastWithTimeObservable, __super__);
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
return SkipLastWithTimeObservable;
}(ObservableBase));
var SkipLastWithTimeObserver = (function (__super__) {
inherits(SkipLastWithTimeObserver, __super__);
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
__super__.call(this);
}
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
return SkipLastWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for skipping elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence.
*/
observableProto.skipLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipLastWithTimeObservable(this, duration, scheduler);
};
================================================
FILE: src/core/linq/observable/skipuntilwithtime.js
================================================
var SkipUntilWithTimeObservable = (function (__super__) {
inherits(SkipUntilWithTimeObservable, __super__);
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
__super__.call(this);
}
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
return SkipUntilWithTimeObservable;
}(ObservableBase));
var SkipUntilWithTimeObserver = (function (__super__) {
inherits(SkipUntilWithTimeObserver, __super__);
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipUntilWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers.
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time.
*
* @examples
* 1 - res = source.skipUntilWithTime(new Date(), [scheduler]);
* 2 - res = source.skipUntilWithTime(5000, [scheduler]);
* @param {Date|Number} startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped until the specified start time.
*/
observableProto.skipUntilWithTime = function (startTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipUntilWithTimeObservable(this, startTime, scheduler);
};
================================================
FILE: src/core/linq/observable/skipwhile.js
================================================
var SkipWhileObservable = (function (__super__) {
inherits(SkipWhileObservable, __super__);
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
return SkipWhileObservable;
}(ObservableBase));
var SkipWhileObserver = (function (__super__) {
inherits(SkipWhileObserver, __super__);
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
__super__.call(this);
}
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWhileObserver;
}(AbstractObserver));
/**
* Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements.
* The element's index is used in the logic of the predicate function.
*
* var res = source.skipWhile(function (value) { return value < 10; });
* var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; });
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.
*/
observableProto.skipWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(this, fn);
};
================================================
FILE: src/core/linq/observable/skipwithtime.js
================================================
var SkipWithTimeObservable = (function (__super__) {
inherits(SkipWithTimeObservable, __super__);
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
__super__.call(this);
}
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
return SkipWithTimeObservable;
}(ObservableBase));
var SkipWithTimeObserver = (function (__super__) {
inherits(SkipWithTimeObserver, __super__);
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
return SkipWithTimeObserver;
}(AbstractObserver));
/**
* Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
* @description
* Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence.
* This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded
* may not execute immediately, despite the zero due time.
*
* Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration.
* @param {Number} duration Duration for skipping elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence.
*/
observableProto.skipWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new SkipWithTimeObservable(this, duration, scheduler);
};
================================================
FILE: src/core/linq/observable/slice.js
================================================
var SliceObservable = (function (__super__) {
inherits(SliceObservable, __super__);
function SliceObservable(source, b, e) {
this.source = source;
this._b = b;
this._e = e;
__super__.call(this);
}
SliceObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SliceObserver(o, this._b, this._e));
};
return SliceObservable;
}(ObservableBase));
var SliceObserver = (function (__super__) {
inherits(SliceObserver, __super__);
function SliceObserver(o, b, e) {
this._o = o;
this._b = b;
this._e = e;
this._i = 0;
__super__.call(this);
}
SliceObserver.prototype.next = function (x) {
if (this._i >= this._b) {
if (this._e === this._i) {
this._o.onCompleted();
} else {
this._o.onNext(x);
}
}
this._i++;
};
SliceObserver.prototype.error = function (e) { this._o.onError(e); };
SliceObserver.prototype.completed = function () { this._o.onCompleted(); };
return SliceObserver;
}(AbstractObserver));
/*
* The slice() method returns a shallow copy of a portion of an Observable into a new Observable object.
* Unlike the array version, this does not support negative numbers for being or end.
* @param {Number} [begin] Zero-based index at which to begin extraction. If omitted, this will default to zero.
* @param {Number} [end] Zero-based index at which to end extraction. slice extracts up to but not including end.
* If omitted, this will emit the rest of the Observable object.
* @returns {Observable} A shallow copy of a portion of an Observable into a new Observable object.
*/
observableProto.slice = function (begin, end) {
var start = begin || 0;
if (start < 0) { throw new Rx.ArgumentOutOfRangeError(); }
if (typeof end === 'number' && end < start) {
throw new Rx.ArgumentOutOfRangeError();
}
return new SliceObservable(this, start, end);
};
================================================
FILE: src/core/linq/observable/some.js
================================================
var SomeObservable = (function (__super__) {
inherits(SomeObservable, __super__);
function SomeObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SomeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SomeObserver(o, this._fn, this.source));
};
return SomeObservable;
}(ObservableBase));
var SomeObserver = (function (__super__) {
inherits(SomeObserver, __super__);
function SomeObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
__super__.call(this);
}
SomeObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (Boolean(result)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
SomeObserver.prototype.error = function (e) { this._o.onError(e); };
SomeObserver.prototype.completed = function () {
this._o.onNext(false);
this._o.onCompleted();
};
return SomeObserver;
}(AbstractObserver));
/**
* Determines whether any element of an observable sequence satisfies a condition if present, else if any items are in the sequence.
* @param {Function} [predicate] A function to test each element for a condition.
* @returns {Observable} An observable sequence containing a single element determining whether any elements in the source sequence pass the test in the specified predicate if given, else if any items are in the sequence.
*/
observableProto.some = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SomeObservable(this, fn);
};
================================================
FILE: src/core/linq/observable/spawn.js
================================================
Observable.wrap = function (fn) {
function createObservable() {
return Observable.spawn.call(this, fn.apply(this, arguments));
}
createObservable.__generatorFunction__ = fn;
return createObservable;
};
var spawn = Observable.spawn = function () {
var gen = arguments[0], self = this, args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return new AnonymousObservable(function (o) {
var g = new CompositeDisposable();
if (isFunction(gen)) { gen = gen.apply(self, args); }
if (!gen || !isFunction(gen.next)) {
o.onNext(gen);
return o.onCompleted();
}
function processGenerator(res) {
var ret = tryCatch(gen.next).call(gen, res);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
processGenerator();
function onError(err) {
var ret = tryCatch(gen.next).call(gen, err);
if (ret === errorObj) { return o.onError(ret.e); }
next(ret);
}
function next(ret) {
if (ret.done) {
o.onNext(ret.value);
o.onCompleted();
return;
}
var obs = toObservable.call(self, ret.value);
var value = null;
var hasValue = false;
if (Observable.isObservable(obs)) {
g.add(obs.subscribe(function(val) {
hasValue = true;
value = val;
}, onError, function() {
hasValue && processGenerator(value);
}));
} else {
onError(new TypeError('type not supported'));
}
}
return g;
});
};
function toObservable(obj) {
if (!obj) { return obj; }
if (Observable.isObservable(obj)) { return obj; }
if (isPromise(obj)) { return Observable.fromPromise(obj); }
if (isGeneratorFunction(obj) || isGenerator(obj)) { return spawn.call(this, obj); }
if (isFunction(obj)) { return thunkToObservable.call(this, obj); }
if (isArrayLike(obj) || isIterable(obj)) { return arrayToObservable.call(this, obj); }
if (isObject(obj)) {return objectToObservable.call(this, obj);}
return obj;
}
function arrayToObservable (obj) {
return Observable.from(obj).concatMap(function(o) {
if(Observable.isObservable(o) || isObject(o)) {
return toObservable.call(null, o);
} else {
return Rx.Observable.just(o);
}
}).toArray();
}
function objectToObservable (obj) {
var results = new obj.constructor(), keys = Object.keys(obj), observables = [];
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
var observable = toObservable.call(this, obj[key]);
if(observable && Observable.isObservable(observable)) {
defer(observable, key);
} else {
results[key] = obj[key];
}
}
return Observable.forkJoin.apply(Observable, observables).map(function() {
return results;
});
function defer (observable, key) {
results[key] = undefined;
observables.push(observable.map(function (next) {
results[key] = next;
}));
}
}
function thunkToObservable(fn) {
var self = this;
return new AnonymousObservable(function (o) {
fn.call(self, function () {
var err = arguments[0], res = arguments[1];
if (err) { return o.onError(err); }
if (arguments.length > 2) {
var args = [];
for (var i = 1, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
res = args;
}
o.onNext(res);
o.onCompleted();
});
});
}
function isGenerator(obj) {
return isFunction (obj.next) && isFunction (obj['throw']);
}
function isGeneratorFunction(obj) {
var ctor = obj.constructor;
if (!ctor) { return false; }
if (ctor.name === 'GeneratorFunction' || ctor.displayName === 'GeneratorFunction') { return true; }
return isGenerator(ctor.prototype);
}
function isObject(val) {
return Object == val.constructor;
}
================================================
FILE: src/core/linq/observable/start.js
================================================
/**
* Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence.
*
* @example
* var res = Rx.Observable.start(function () { console.log('hello'); });
* var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout);
* var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console);
*
* @param {Function} func Function to run asynchronously.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*
* Remarks
* * The function is called immediately, not during the subscription of the resulting sequence.
* * Multiple subscriptions to the resulting sequence can observe the function's result.
*/
Observable.start = function (func, context, scheduler) {
return observableToAsync(func, context, scheduler)();
};
================================================
FILE: src/core/linq/observable/startasync.js
================================================
/**
* Invokes the asynchronous function, surfacing the result through an observable sequence.
* @param {Function} functionAsync Asynchronous function which returns a Promise to run.
* @returns {Observable} An observable sequence exposing the function's result value, or an exception.
*/
Observable.startAsync = function (functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) { return observableThrow(promise.e); }
return observableFromPromise(promise);
};
================================================
FILE: src/core/linq/observable/startwith.js
================================================
/**
* Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend.
* @example
* var res = source.startWith(1, 2, 3);
* var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3);
* @param {Arguments} args The specified values to prepend to the observable sequence
* @returns {Observable} The source sequence prepended with the specified values.
*/
observableProto.startWith = function () {
var values, scheduler, start = 0;
if (!!arguments.length && isScheduler(arguments[0])) {
scheduler = arguments[0];
start = 1;
} else {
scheduler = immediateScheduler;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return observableConcat.apply(null, [observableFromArray(args, scheduler), this]);
};
================================================
FILE: src/core/linq/observable/subscribeon.js
================================================
var SubscribeOnObservable = (function (__super__) {
inherits(SubscribeOnObservable, __super__);
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
return SubscribeOnObservable;
}(ObservableBase));
/**
* Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
* see the remarks section for more information on the distinction between subscribeOn and observeOn.
* This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
* callbacks on a scheduler, use observeOn.
* @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on.
* @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
*/
observableProto.subscribeOn = function (scheduler) {
return new SubscribeOnObservable(this, scheduler);
};
================================================
FILE: src/core/linq/observable/sum.js
================================================
var SumObservable = (function (__super__) {
inherits(SumObservable, __super__);
function SumObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
SumObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SumObserver(o, this._fn, this.source));
};
return SumObservable;
}(ObservableBase));
var SumObserver = (function (__super__) {
inherits(SumObserver, __super__);
function SumObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
__super__.call(this);
}
SumObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
this._c += result;
} else {
this._c += x;
}
};
SumObserver.prototype.error = function (e) { this._o.onError(e); };
SumObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
return SumObserver;
}(AbstractObserver));
/**
* Computes the sum of a sequence of values that are obtained by invoking an optional transform function on each element of the input sequence, else if not specified computes the sum on each item in the sequence.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the sum of the values in the source sequence.
*/
observableProto.sum = function (keySelector, thisArg) {
var fn = bindCallback(keySelector, thisArg, 3);
return new SumObservable(this, fn);
};
================================================
FILE: src/core/linq/observable/switchfirst.js
================================================
var SwitchFirstObservable = (function (__super__) {
inherits(SwitchFirstObservable, __super__);
function SwitchFirstObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
return SwitchFirstObservable;
}(ObservableBase));
var SwitchFirstObserver = (function(__super__) {
inherits(SwitchFirstObserver, __super__);
function SwitchFirstObserver(state) {
this._s = state;
__super__.call(this);
}
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = observableFromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
inherits(InnerObserver, __super__);
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
__super__.call(this);
}
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
return SwitchFirstObserver;
}(AbstractObserver));
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
observableProto.switchFirst = function () {
return new SwitchFirstObservable(this);
};
================================================
FILE: src/core/linq/observable/takelast.js
================================================
var TakeLastObserver = (function (__super__) {
inherits(TakeLastObserver, __super__);
function TakeLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastObserver.prototype.completed = function () {
while (this._q.length > 0) { this._o.onNext(this._q.shift()); }
this._o.onCompleted();
};
return TakeLastObserver;
}(AbstractObserver));
/**
* Returns a specified number of contiguous elements from the end of an observable sequence.
* @description
* This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of
* the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence.
*/
observableProto.takeLast = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastObserver(o, count));
}, source);
};
================================================
FILE: src/core/linq/observable/takelastbuffer.js
================================================
var TakeLastBufferObserver = (function (__super__) {
inherits(TakeLastBufferObserver, __super__);
function TakeLastBufferObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
__super__.call(this);
}
TakeLastBufferObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._q.shift();
};
TakeLastBufferObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeLastBufferObserver.prototype.completed = function () {
this._o.onNext(this._q);
this._o.onCompleted();
};
return TakeLastBufferObserver;
}(AbstractObserver));
/**
* Returns an array with the specified number of contiguous elements from the end of an observable sequence.
*
* @description
* This operator accumulates a buffer with a length enough to store count elements. Upon completion of the
* source sequence, this buffer is produced on the result sequence.
* @param {Number} count Number of elements to take from the end of the source sequence.
* @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence.
*/
observableProto.takeLastBuffer = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
var source = this;
return new AnonymousObservable(function (o) {
return source.subscribe(new TakeLastBufferObserver(o, count));
}, source);
};
================================================
FILE: src/core/linq/observable/takelastbufferwithtime.js
================================================
/**
* Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastBufferWithTime = function (duration, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (o) {
var q = [];
return source.subscribe(function (x) {
var now = scheduler.now();
q.push({ interval: now, value: x });
while (q.length > 0 && now - q[0].interval >= duration) {
q.shift();
}
}, function (e) { o.onError(e); }, function () {
var now = scheduler.now(), res = [];
while (q.length > 0) {
var next = q.shift();
now - next.interval <= duration && res.push(next.value);
}
o.onNext(res);
o.onCompleted();
});
}, source);
};
================================================
FILE: src/core/linq/observable/takelastwithtime.js
================================================
var TakeLastWithTimeObservable = (function (__super__) {
inherits(TakeLastWithTimeObservable, __super__);
function TakeLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
TakeLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeLastWithTimeObserver(o, this._d, this._s));
};
return TakeLastWithTimeObservable;
}(ObservableBase));
var TakeLastWithTimeObserver = (function (__super__) {
inherits(TakeLastWithTimeObserver, __super__);
function TakeLastWithTimeObserver(o, d, s) {
this._o = o;
this._d = d;
this._s = s;
this._q = [];
__super__.call(this);
}
TakeLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._q.shift();
}
};
TakeLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0) {
var next = this._q.shift();
if (now - next.interval <= this._d) { this._o.onNext(next.value); }
}
this._o.onCompleted();
};
return TakeLastWithTimeObserver;
}(AbstractObserver));
/**
* Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements.
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the end of the sequence.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence.
*/
observableProto.takeLastWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeLastWithTimeObservable(this, duration, scheduler);
};
================================================
FILE: src/core/linq/observable/takeuntilwithtime.js
================================================
/**
* Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers.
* @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately.
* @param {Scheduler} [scheduler] Scheduler to run the timer on.
* @returns {Observable} An observable sequence with the elements taken until the specified end time.
*/
observableProto.takeUntilWithTime = function (endTime, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var source = this;
return new AnonymousObservable(function (o) {
return new BinaryDisposable(
scheduler.scheduleFuture(o, endTime, function (_, o) { o.onCompleted(); }),
source.subscribe(o));
}, source);
};
================================================
FILE: src/core/linq/observable/takewhile.js
================================================
var TakeWhileObservable = (function (__super__) {
inherits(TakeWhileObservable, __super__);
function TakeWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
__super__.call(this);
}
TakeWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeWhileObserver(o, this));
};
return TakeWhileObservable;
}(ObservableBase));
var TakeWhileObserver = (function (__super__) {
inherits(TakeWhileObserver, __super__);
function TakeWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = true;
__super__.call(this);
}
TakeWhileObserver.prototype.next = function (x) {
if (this._r) {
this._r = tryCatch(this._p._fn)(x, this._i++, this._p);
if (this._r === errorObj) { return this._o.onError(this._r.e); }
}
if (this._r) {
this._o.onNext(x);
} else {
this._o.onCompleted();
}
};
TakeWhileObserver.prototype.error = function (e) { this._o.onError(e); };
TakeWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeWhileObserver;
}(AbstractObserver));
/**
* Returns elements from an observable sequence as long as a specified condition is true.
* The element's index is used in the logic of the predicate function.
* @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes.
*/
observableProto.takeWhile = function (predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new TakeWhileObservable(this, fn);
};
================================================
FILE: src/core/linq/observable/takewithtime.js
================================================
var TakeWithTimeObservable = (function (__super__) {
inherits(TakeWithTimeObservable, __super__);
function TakeWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
__super__.call(this);
}
function scheduleMethod(s, o) {
o.onCompleted();
}
TakeWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(o, this._d, scheduleMethod),
this.source.subscribe(o)
);
};
return TakeWithTimeObservable;
}(ObservableBase));
/**
* Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers.
*
* @example
* 1 - res = source.takeWithTime(5000, [optional scheduler]);
* @description
* This operator accumulates a queue with a length enough to store elements received during the initial duration window.
* As more elements are received, elements older than the specified duration are taken from the queue and produced on the
* result sequence. This causes elements to be delayed with duration.
* @param {Number} duration Duration for taking elements from the start of the sequence.
* @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout.
* @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence.
*/
observableProto.takeWithTime = function (duration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TakeWithTimeObservable(this, duration, scheduler);
};
================================================
FILE: src/core/linq/observable/thendo.js
================================================
/**
* Matches when the observable sequence has an available value and projects the value.
*
* @param {Function} selector Selector that will be invoked for values in the source sequence.
* @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
observableProto.thenDo = function (selector) {
return new Pattern([this]).thenDo(selector);
};
================================================
FILE: src/core/linq/observable/throttle.js
================================================
/**
* Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
* @param {Number} windowDuration time to wait before emitting another item after emitting the last item
* @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
* @returns {Observable} An Observable that performs the throttle operation.
*/
observableProto.throttle = function (windowDuration, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
================================================
FILE: src/core/linq/observable/timeinterval.js
================================================
var TimeIntervalObservable = (function (__super__) {
inherits(TimeIntervalObservable, __super__);
function TimeIntervalObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimeIntervalObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimeIntervalObserver(o, this._s));
};
return TimeIntervalObservable;
}(ObservableBase));
var TimeIntervalObserver = (function (__super__) {
inherits(TimeIntervalObserver, __super__);
function TimeIntervalObserver(o, s) {
this._o = o;
this._s = s;
this._l = s.now();
__super__.call(this);
}
TimeIntervalObserver.prototype.next = function (x) {
var now = this._s.now(), span = now - this._l;
this._l = now;
this._o.onNext({ value: x, interval: span });
};
TimeIntervalObserver.prototype.error = function (e) { this._o.onError(e); };
TimeIntervalObserver.prototype.completed = function () { this._o.onCompleted(); };
return TimeIntervalObserver;
}(AbstractObserver));
/**
* Records the time interval between consecutive values in an observable sequence.
*
* @example
* 1 - res = source.timeInterval();
* 2 - res = source.timeInterval(Rx.Scheduler.timeout);
*
* @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence with time interval information on values.
*/
observableProto.timeInterval = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimeIntervalObservable(this, scheduler);
};
================================================
FILE: src/core/linq/observable/timeout.js
================================================
var TimeoutError = Rx.TimeoutError = function(message) {
this.message = message || 'Timeout has occurred';
this.name = 'TimeoutError';
Error.call(this);
};
TimeoutError.prototype = Object.create(Error.prototype);
function timeoutWithSelector(source, firstTimeout, timeoutDurationSelector, other) {
if (isFunction(firstTimeout)) {
other = timeoutDurationSelector;
timeoutDurationSelector = firstTimeout;
firstTimeout = observableNever();
}
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var subscription = new SerialDisposable(),
timer = new SerialDisposable(),
original = new SingleAssignmentDisposable();
subscription.setDisposable(original);
var id = 0, switched = false;
function setTimer(timeout) {
var myId = id, d = new SingleAssignmentDisposable();
function timerWins() {
switched = (myId === id);
return switched;
}
timer.setDisposable(d);
d.setDisposable(timeout.subscribe(function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
d.dispose();
}, function (e) {
timerWins() && o.onError(e);
}, function () {
timerWins() && subscription.setDisposable(other.subscribe(o));
}));
};
setTimer(firstTimeout);
function oWins() {
var res = !switched;
if (res) { id++; }
return res;
}
original.setDisposable(source.subscribe(function (x) {
if (oWins()) {
o.onNext(x);
var timeout = tryCatch(timeoutDurationSelector)(x);
if (timeout === errorObj) { return o.onError(timeout.e); }
setTimer(isPromise(timeout) ? observableFromPromise(timeout) : timeout);
}
}, function (e) {
oWins() && o.onError(e);
}, function () {
oWins() && o.onCompleted();
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
function timeout(source, dueTime, other, scheduler) {
if (isScheduler(other)) {
scheduler = other;
other = observableThrow(new TimeoutError());
}
if (other instanceof Error) { other = observableThrow(other); }
isScheduler(scheduler) || (scheduler = defaultScheduler);
Observable.isObservable(other) || (other = observableThrow(new TimeoutError()));
return new AnonymousObservable(function (o) {
var id = 0,
original = new SingleAssignmentDisposable(),
subscription = new SerialDisposable(),
switched = false,
timer = new SerialDisposable();
subscription.setDisposable(original);
function createTimer() {
var myId = id;
timer.setDisposable(scheduler.scheduleFuture(null, dueTime, function () {
switched = id === myId;
if (switched) {
isPromise(other) && (other = observableFromPromise(other));
subscription.setDisposable(other.subscribe(o));
}
}));
}
createTimer();
original.setDisposable(source.subscribe(function (x) {
if (!switched) {
id++;
o.onNext(x);
createTimer();
}
}, function (e) {
if (!switched) {
id++;
o.onError(e);
}
}, function () {
if (!switched) {
id++;
o.onCompleted();
}
}));
return new BinaryDisposable(subscription, timer);
}, source);
}
observableProto.timeout = function () {
var firstArg = arguments[0];
if (firstArg instanceof Date || typeof firstArg === 'number') {
return timeout(this, firstArg, arguments[1], arguments[2]);
} else if (Observable.isObservable(firstArg) || isFunction(firstArg)) {
return timeoutWithSelector(this, firstArg, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
================================================
FILE: src/core/linq/observable/timer.js
================================================
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) {
var period;
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return _observableTimer(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return observableTimerDateAndPeriod(dueTime, periodOrScheduler, scheduler);
}
return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler);
};
================================================
FILE: src/core/linq/observable/timestamp.js
================================================
var TimestampObservable = (function (__super__) {
inherits(TimestampObservable, __super__);
function TimestampObservable(source, s) {
this.source = source;
this._s = s;
__super__.call(this);
}
TimestampObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TimestampObserver(o, this._s));
};
return TimestampObservable;
}(ObservableBase));
var TimestampObserver = (function (__super__) {
inherits(TimestampObserver, __super__);
function TimestampObserver(o, s) {
this._o = o;
this._s = s;
__super__.call(this);
}
TimestampObserver.prototype.next = function (x) {
this._o.onNext({ value: x, timestamp: this._s.now() });
};
TimestampObserver.prototype.error = function (e) {
this._o.onError(e);
};
TimestampObserver.prototype.completed = function () {
this._o.onCompleted();
};
return TimestampObserver;
}(AbstractObserver));
/**
* Records the timestamp for each value in an observable sequence.
*
* @example
* 1 - res = source.timestamp(); // produces { value: x, timestamp: ts }
* 2 - res = source.timestamp(Rx.Scheduler.default);
*
* @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the default scheduler is used.
* @returns {Observable} An observable sequence with timestamp information on values.
*/
observableProto.timestamp = function (scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new TimestampObservable(this, scheduler);
};
================================================
FILE: src/core/linq/observable/toasync.js
================================================
/**
* Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler.
* @param {Function} function Function to convert to an asynchronous function.
* @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout.
* @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @returns {Function} Asynchronous function.
*/
var observableToAsync = Observable.toAsync = function (func, context, scheduler) {
isScheduler(scheduler) || (scheduler = defaultScheduler);
return function () {
var args = arguments,
subject = new AsyncSubject();
scheduler.schedule(null, function () {
var result;
try {
result = func.apply(context, args);
} catch (e) {
subject.onError(e);
return;
}
subject.onNext(result);
subject.onCompleted();
});
return subject.asObservable();
};
};
================================================
FILE: src/core/linq/observable/tomap.js
================================================
var ToMapObservable = (function (__super__) {
inherits(ToMapObservable, __super__);
function ToMapObservable(source, k, e) {
this.source = source;
this._k = k;
this._e = e;
__super__.call(this);
}
ToMapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToMapObserver(o, this._k, this._e));
};
return ToMapObservable;
}(ObservableBase));
var ToMapObserver = (function (__super__) {
inherits(ToMapObserver, __super__);
function ToMapObserver(o, k, e) {
this._o = o;
this._k = k;
this._e = e;
this._m = new root.Map();
__super__.call(this);
}
ToMapObserver.prototype.next = function (x) {
var key = tryCatch(this._k)(x);
if (key === errorObj) { return this._o.onError(key.e); }
var elem = x;
if (this._e) {
elem = tryCatch(this._e)(x);
if (elem === errorObj) { return this._o.onError(elem.e); }
}
this._m.set(key, elem);
};
ToMapObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToMapObserver.prototype.completed = function () {
this._o.onNext(this._m);
this._o.onCompleted();
};
return ToMapObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Map if it exists.
* @param {Function} keySelector A function which produces the key for the Map.
* @param {Function} [elementSelector] An optional function which produces the element for the Map. If not present, defaults to the value from the observable sequence.
* @returns {Observable} An observable sequence with a single value of a Map containing the values from the observable sequence.
*/
observableProto.toMap = function (keySelector, elementSelector) {
if (typeof root.Map === 'undefined') { throw new TypeError(); }
return new ToMapObservable(this, keySelector, elementSelector);
};
================================================
FILE: src/core/linq/observable/topromise.js
================================================
/*
* Converts an existing observable sequence to an ES6 Compatible Promise
* @example
* var promise = Rx.Observable.return(42).toPromise(RSVP.Promise);
*
* // With config
* Rx.config.Promise = RSVP.Promise;
* var promise = Rx.Observable.return(42).toPromise();
* @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise.
* @returns {Promise} An ES6 compatible promise with the last value from the observable sequence.
*/
observableProto.toPromise = function (promiseCtor) {
promiseCtor || (promiseCtor = Rx.config.Promise);
if (!promiseCtor) { throw new NotSupportedError('Promise type not provided nor in Rx.config.Promise'); }
var source = this;
return new promiseCtor(function (resolve, reject) {
// No cancellation can be done
var value;
source.subscribe(function (v) {
value = v;
}, reject, function () {
resolve(value);
});
});
};
================================================
FILE: src/core/linq/observable/toset.js
================================================
var ToSetObservable = (function (__super__) {
inherits(ToSetObservable, __super__);
function ToSetObservable(source) {
this.source = source;
__super__.call(this);
}
ToSetObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ToSetObserver(o));
};
return ToSetObservable;
}(ObservableBase));
var ToSetObserver = (function (__super__) {
inherits(ToSetObserver, __super__);
function ToSetObserver(o) {
this._o = o;
this._s = new root.Set();
__super__.call(this);
}
ToSetObserver.prototype.next = function (x) {
this._s.add(x);
};
ToSetObserver.prototype.error = function (e) {
this._o.onError(e);
};
ToSetObserver.prototype.completed = function () {
this._o.onNext(this._s);
this._o.onCompleted();
};
return ToSetObserver;
}(AbstractObserver));
/**
* Converts the observable sequence to a Set if it exists.
* @returns {Observable} An observable sequence with a single value of a Set containing the values from the observable sequence.
*/
observableProto.toSet = function () {
if (typeof root.Set === 'undefined') { throw new TypeError(); }
return new ToSetObservable(this);
};
================================================
FILE: src/core/linq/observable/transduce.js
================================================
var TransduceObserver = (function (__super__) {
inherits(TransduceObserver, __super__);
function TransduceObserver(o, xform) {
this._o = o;
this._xform = xform;
__super__.call(this);
}
TransduceObserver.prototype.next = function (x) {
var res = tryCatch(this._xform['@@transducer/step']).call(this._xform, this._o, x);
if (res === errorObj) { this._o.onError(res.e); }
};
TransduceObserver.prototype.error = function (e) { this._o.onError(e); };
TransduceObserver.prototype.completed = function () {
this._xform['@@transducer/result'](this._o);
};
return TransduceObserver;
}(AbstractObserver));
function transformForObserver(o) {
return {
'@@transducer/init': function() {
return o;
},
'@@transducer/step': function(obs, input) {
return obs.onNext(input);
},
'@@transducer/result': function(obs) {
return obs.onCompleted();
}
};
}
/**
* Executes a transducer to transform the observable sequence
* @param {Transducer} transducer A transducer to execute
* @returns {Observable} An Observable sequence containing the results from the transducer.
*/
observableProto.transduce = function(transducer) {
var source = this;
return new AnonymousObservable(function(o) {
var xform = transducer(transformForObserver(o));
return source.subscribe(new TransduceObserver(o, xform));
}, source);
};
================================================
FILE: src/core/linq/observable/using.js
================================================
var UsingObservable = (function (__super__) {
inherits(UsingObservable, __super__);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
__super__.call(this);
}
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = disposableEmpty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(observableThrow(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(observableThrow(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
return UsingObservable;
}(ObservableBase));
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
Observable.using = function (resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
================================================
FILE: src/core/linq/observable/when.js
================================================
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
Observable.when = function () {
var len = arguments.length, plans;
if (Array.isArray(arguments[0])) {
plans = arguments[0];
} else {
plans = new Array(len);
for(var i = 0; i < len; i++) { plans[i] = arguments[i]; }
}
return new AnonymousObservable(function (o) {
var activePlans = [],
externalSubscriptions = new Map();
var outObserver = observerCreate(
function (x) { o.onNext(x); },
function (err) {
externalSubscriptions.forEach(function (v) { v.onError(err); });
o.onError(err);
},
function (x) { o.onCompleted(); }
);
try {
for (var i = 0, len = plans.length; i < len; i++) {
activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return observableThrow(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
});
};
================================================
FILE: src/core/linq/observable/while.js
================================================
/**
* Repeats source as long as condition holds emulating a while loop.
* There is an alias for this method called 'whileDo' for browsers = 0 && c % skip === 0 && q.shift().onCompleted();
++n % skip === 0 && createWindow();
},
function (e) {
while (q.length > 0) { q.shift().onError(e); }
observer.onError(e);
},
function () {
while (q.length > 0) { q.shift().onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
================================================
FILE: src/core/linq/observable/windowwithtime.js
================================================
/**
* Projects each element of an observable sequence into zero or more windows which are produced based on timing information.
* @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds).
* @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTime = observableProto.windowTime = function (timeSpan, timeShiftOrScheduler, scheduler) {
var source = this, timeShift;
timeShiftOrScheduler == null && (timeShift = timeSpan);
isScheduler(scheduler) || (scheduler = defaultScheduler);
if (typeof timeShiftOrScheduler === 'number') {
timeShift = timeShiftOrScheduler;
} else if (isScheduler(timeShiftOrScheduler)) {
timeShift = timeSpan;
scheduler = timeShiftOrScheduler;
}
return new AnonymousObservable(function (observer) {
var groupDisposable,
nextShift = timeShift,
nextSpan = timeSpan,
q = [],
refCountDisposable,
timerD = new SerialDisposable(),
totalTime = 0;
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable);
function createTimer () {
var m = new SingleAssignmentDisposable(),
isSpan = false,
isShift = false;
timerD.setDisposable(m);
if (nextSpan === nextShift) {
isSpan = true;
isShift = true;
} else if (nextSpan < nextShift) {
isSpan = true;
} else {
isShift = true;
}
var newTotalTime = isSpan ? nextSpan : nextShift,
ts = newTotalTime - totalTime;
totalTime = newTotalTime;
if (isSpan) {
nextSpan += timeShift;
}
if (isShift) {
nextShift += timeShift;
}
m.setDisposable(scheduler.scheduleFuture(null, ts, function () {
if (isShift) {
var s = new Subject();
q.push(s);
observer.onNext(addRef(s, refCountDisposable));
}
isSpan && q.shift().onCompleted();
createTimer();
}));
};
q.push(new Subject());
observer.onNext(addRef(q[0], refCountDisposable));
createTimer();
groupDisposable.add(source.subscribe(
function (x) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onNext(x); }
},
function (e) {
for (var i = 0, len = q.length; i < len; i++) { q[i].onError(e); }
observer.onError(e);
},
function () {
for (var i = 0, len = q.length; i < len; i++) { q[i].onCompleted(); }
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
================================================
FILE: src/core/linq/observable/windowwithtimeorcount.js
================================================
/**
* Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed.
* @param {Number} timeSpan Maximum time length of a window.
* @param {Number} count Maximum element count of a window.
* @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence of windows.
*/
observableProto.windowWithTimeOrCount = observableProto.windowTimeOrCount = function (timeSpan, count, scheduler) {
var source = this;
isScheduler(scheduler) || (scheduler = defaultScheduler);
return new AnonymousObservable(function (observer) {
var timerD = new SerialDisposable(),
groupDisposable = new CompositeDisposable(timerD),
refCountDisposable = new RefCountDisposable(groupDisposable),
n = 0,
windowId = 0,
s = new Subject();
function createTimer(id) {
var m = new SingleAssignmentDisposable();
timerD.setDisposable(m);
m.setDisposable(scheduler.scheduleFuture(null, timeSpan, function () {
if (id !== windowId) { return; }
n = 0;
var newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
createTimer(newId);
}));
}
observer.onNext(addRef(s, refCountDisposable));
createTimer(0);
groupDisposable.add(source.subscribe(
function (x) {
var newId = 0, newWindow = false;
s.onNext(x);
if (++n === count) {
newWindow = true;
n = 0;
newId = ++windowId;
s.onCompleted();
s = new Subject();
observer.onNext(addRef(s, refCountDisposable));
}
newWindow && createTimer(newId);
},
function (e) {
s.onError(e);
observer.onError(e);
}, function () {
s.onCompleted();
observer.onCompleted();
}
));
return refCountDisposable;
}, source);
};
================================================
FILE: src/core/linq/observable/zip.js
================================================
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
* @param arguments Observable sources.
* @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources.
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
Observable.zip = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
if (Array.isArray(args[0])) {
args = isFunction(args[1]) ? args[0].concat(args[1]) : args[0];
}
var first = args.shift();
return first.zip.apply(first, args);
};
================================================
FILE: src/core/linq/observable/zipiterable.js
================================================
function falseFactory() { return false; }
function emptyArrayFactory() { return []; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var ZipIterableObservable = (function(__super__) {
inherits(ZipIterableObservable, __super__);
function ZipIterableObservable(sources, cb) {
this.sources = sources;
this._cb = cb;
__super__.call(this);
}
ZipIterableObservable.prototype.subscribeCore = function (o) {
var sources = this.sources, len = sources.length, subscriptions = new Array(len);
var state = {
q: arrayInitialize(len, emptyArrayFactory),
done: arrayInitialize(len, falseFactory),
cb: this._cb,
o: o
};
for (var i = 0; i < len; i++) {
(function (i) {
var source = sources[i], sad = new SingleAssignmentDisposable();
(isArrayLike(source) || isIterable(source)) && (source = observableFrom(source));
subscriptions[i] = sad;
sad.setDisposable(source.subscribe(new ZipIterableObserver(state, i)));
}(i));
}
return new NAryDisposable(subscriptions);
};
return ZipIterableObservable;
}(ObservableBase));
var ZipIterableObserver = (function (__super__) {
inherits(ZipIterableObserver, __super__);
function ZipIterableObserver(s, i) {
this._s = s;
this._i = i;
__super__.call(this);
}
function notEmpty(x) { return x.length > 0; }
function shiftEach(x) { return x.shift(); }
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipIterableObserver.prototype.next = function (x) {
this._s.q[this._i].push(x);
if (this._s.q.every(notEmpty)) {
var queuedValues = this._s.q.map(shiftEach),
res = tryCatch(this._s.cb).apply(null, queuedValues);
if (res === errorObj) { return this._s.o.onError(res.e); }
this._s.o.onNext(res);
} else if (this._s.done.filter(notTheSame(this._i)).every(identity)) {
this._s.o.onCompleted();
}
};
ZipIterableObserver.prototype.error = function (e) { this._s.o.onError(e); };
ZipIterableObserver.prototype.completed = function () {
this._s.done[this._i] = true;
this._s.done.every(identity) && this._s.o.onCompleted();
};
return ZipIterableObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
observableProto.zipIterable = function () {
if (arguments.length === 0) { throw new Error('invalid arguments'); }
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
var parent = this;
args.unshift(parent);
return new ZipIterableObservable(args, resultSelector);
};
================================================
FILE: src/core/longstacktraces/longstackbegin.js
================================================
Rx.config.longStackSupport = false;
var hasStacks = false, stacks = tryCatch(function () { throw new Error(); })();
hasStacks = !!stacks.e && !!stacks.e.stack;
// All code after this point will be filtered from stack traces reported by RxJS
var rStartingLine = captureLine(), rFileName;
================================================
FILE: src/core/longstacktraces/longstackend.js
================================================
// All code before this point will be filtered from stack traces.
var rEndingLine = captureLine();
================================================
FILE: src/core/longstacktraces/longstacktraces.js
================================================
var STACK_JUMP_SEPARATOR = 'From previous event:';
function makeStackTraceLong(error, observable) {
// If possible, transform the error stack trace by removing Node and RxJS
// cruft, then concatenating with the stack trace of `observable`.
if (hasStacks &&
observable.stack &&
typeof error === 'object' &&
error !== null &&
error.stack &&
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var o = observable; !!o; o = o.source) {
if (o.stack) {
stacks.unshift(o.stack);
}
}
stacks.unshift(error.stack);
var concatedStacks = stacks.join('\n' + STACK_JUMP_SEPARATOR + '\n');
error.stack = filterStackString(concatedStacks);
}
}
function filterStackString(stackString) {
var lines = stackString.split('\n'), desiredLines = [];
for (var i = 0, len = lines.length; i < len; i++) {
var line = lines[i];
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
desiredLines.push(line);
}
}
return desiredLines.join('\n');
}
function isInternalFrame(stackLine) {
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
if (!fileNameAndLineNumber) {
return false;
}
var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1];
return fileName === rFileName &&
lineNumber >= rStartingLine &&
lineNumber <= rEndingLine;
}
function isNodeFrame(stackLine) {
return stackLine.indexOf('(module.js:') !== -1 ||
stackLine.indexOf('(node.js:') !== -1;
}
function captureLine() {
if (!hasStacks) { return; }
try {
throw new Error();
} catch (e) {
var lines = e.stack.split('\n');
var firstLine = lines[0].indexOf('@') > 0 ? lines[1] : lines[2];
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
if (!fileNameAndLineNumber) { return; }
rFileName = fileNameAndLineNumber[0];
return fileNameAndLineNumber[1];
}
}
function getFileNameAndLineNumber(stackLine) {
// Named functions: 'at functionName (filename:lineNumber:columnNumber)'
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
if (attempt1) { return [attempt1[1], Number(attempt1[2])]; }
// Anonymous functions: 'at filename:lineNumber:columnNumber'
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
if (attempt2) { return [attempt2[1], Number(attempt2[2])]; }
// Firefox style: 'function@filename:lineNumber or @filename:lineNumber'
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
if (attempt3) { return [attempt3[1], Number(attempt3[2])]; }
}
================================================
FILE: src/core/notification.js
================================================
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification() {
}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObserver(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
return Notification;
})();
var OnNextNotification = (function (__super__) {
inherits(OnNextNotification, __super__);
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
return OnNextNotification;
}(Notification));
var OnErrorNotification = (function (__super__) {
inherits(OnErrorNotification, __super__);
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
return OnErrorNotification;
}(Notification));
var OnCompletedNotification = (function (__super__) {
inherits(OnCompletedNotification, __super__);
function OnCompletedNotification() {
this.kind = 'C';
}
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
return OnCompletedNotification;
}(Notification));
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
var notificationCreateOnNext = Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
var notificationCreateOnError = Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
var notificationCreateOnCompleted = Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
================================================
FILE: src/core/observable.js
================================================
var observableProto;
/**
* Represents a push-style collection.
*/
var Observable = Rx.Observable = (function () {
function makeSubscribe(self, subscribe) {
return function (o) {
var oldOnError = o.onError;
o.onError = function (e) {
makeStackTraceLong(e, self);
oldOnError.call(o, e);
};
return subscribe.call(self, o);
};
}
function Observable() {
if (Rx.config.longStackSupport && hasStacks) {
var oldSubscribe = this._subscribe;
var e = tryCatch(thrower)(new Error()).e;
this.stack = e.stack.substring(e.stack.indexOf('\n') + 1);
this._subscribe = makeSubscribe(this, oldSubscribe);
}
}
observableProto = Observable.prototype;
/**
* Determines whether the given object is an Observable
* @param {Any} An object to determine whether it is an Observable
* @returns {Boolean} true if an Observable, else false.
*/
Observable.isObservable = function (o) {
return o && isFunction(o.subscribe);
};
/**
* Subscribes an o to the observable sequence.
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onNext The function to invoke on each element in the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnNext = function (onNext, thisArg) {
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
};
/**
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnError = function (onError, thisArg) {
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
};
/**
* Subscribes to the next value in the sequence with an optional "this" argument.
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
};
return Observable;
})();
================================================
FILE: src/core/observeonobserver.js
================================================
var ObserveOnObserver = (function (__super__) {
inherits(ObserveOnObserver, __super__);
function ObserveOnObserver(scheduler, observer, cancel) {
__super__.call(this, scheduler, observer);
this._cancel = cancel;
}
ObserveOnObserver.prototype.next = function (value) {
__super__.prototype.next.call(this, value);
this.ensureActive();
};
ObserveOnObserver.prototype.error = function (e) {
__super__.prototype.error.call(this, e);
this.ensureActive();
};
ObserveOnObserver.prototype.completed = function () {
__super__.prototype.completed.call(this);
this.ensureActive();
};
ObserveOnObserver.prototype.dispose = function () {
__super__.prototype.dispose.call(this);
this._cancel && this._cancel.dispose();
this._cancel = null;
};
return ObserveOnObserver;
})(ScheduledObserver);
================================================
FILE: src/core/observer-extras.js
================================================
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
*
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var handlerFunc = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return handlerFunc(notificationCreateOnNext(x));
}, function (e) {
return handlerFunc(notificationCreateOnError(e));
}, function () {
return handlerFunc(notificationCreateOnCompleted());
});
};
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var source = this;
return new AnonymousObserver(
function (x) { source.onNext(x); },
function (e) { source.onError(e); },
function () { source.onCompleted(); }
);
};
================================================
FILE: src/core/observer-lite.js
================================================
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
================================================
FILE: src/core/observer.js
================================================
/**
* Supports push-style iteration over an observable sequence.
*/
var Observer = Rx.Observer = function () { };
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
Observer.prototype.toNotifier = function () {
var observer = this;
return function (n) { return n.accept(observer); };
};
/**
* Hides the identity of an observer.
* @returns An observer that hides the identity of the specified observer.
*/
Observer.prototype.asObserver = function () {
var self = this;
return new AnonymousObserver(
function (x) { self.onNext(x); },
function (err) { self.onError(err); },
function () { self.onCompleted(); });
};
/**
* Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods.
* If a violation is detected, an Error is thrown from the offending observer method call.
* @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer.
*/
Observer.prototype.checked = function () { return new CheckedObserver(this); };
/**
* Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions.
* @param {Function} [onNext] Observer's OnNext action implementation.
* @param {Function} [onError] Observer's OnError action implementation.
* @param {Function} [onCompleted] Observer's OnCompleted action implementation.
* @returns {Observer} The observer object implemented using the given actions.
*/
var observerCreate = Observer.create = function (onNext, onError, onCompleted) {
onNext || (onNext = noop);
onError || (onError = defaultError);
onCompleted || (onCompleted = noop);
return new AnonymousObserver(onNext, onError, onCompleted);
};
/**
* Creates an observer from a notification callback.
* @param {Function} handler Action that handles a notification.
* @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives.
*/
Observer.fromNotifier = function (handler, thisArg) {
var cb = bindCallback(handler, thisArg, 1);
return new AnonymousObserver(function (x) {
return cb(notificationCreateOnNext(x));
}, function (e) {
return cb(notificationCreateOnError(e));
}, function () {
return cb(notificationCreateOnCompleted());
});
};
/**
* Schedules the invocation of observer methods on the given scheduler.
* @param {Scheduler} scheduler Scheduler to schedule observer messages on.
* @returns {Observer} Observer whose messages are scheduled on the given scheduler.
*/
Observer.prototype.notifyOn = function (scheduler) {
return new ObserveOnObserver(scheduler, this);
};
Observer.prototype.makeSafe = function(disposable) {
return new AnonymousSafeObserver(this._onNext, this._onError, this._onCompleted, disposable);
};
================================================
FILE: src/core/perf/observablebase.js
================================================
var ObservableBase = Rx.ObservableBase = (function (__super__) {
inherits(ObservableBase, __super__);
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber :
isFunction(subscriber) ? disposableCreate(subscriber) : disposableEmpty;
}
function setDisposable(s, state) {
var ado = state[0], self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(errorObj.e)) { thrower(errorObj.e); }
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
__super__.call(this);
}
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o), state = [ado, this];
if (currentThreadScheduler.scheduleRequired()) {
currentThreadScheduler.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = notImplemented;
return ObservableBase;
}(Observable));
================================================
FILE: src/core/perf/operators/combinelatest.js
================================================
function falseFactory() { return false; }
function argumentsToArray() {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return args;
}
var CombineLatestObservable = (function(__super__) {
inherits(CombineLatestObservable, __super__);
function CombineLatestObservable(params, cb) {
this._params = params;
this._cb = cb;
__super__.call(this);
}
CombineLatestObservable.prototype.subscribeCore = function(observer) {
var len = this._params.length,
subscriptions = new Array(len);
var state = {
hasValue: arrayInitialize(len, falseFactory),
hasValueAll: false,
isDone: arrayInitialize(len, falseFactory),
values: new Array(len)
};
for (var i = 0; i < len; i++) {
var source = this._params[i], sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = observableFromPromise(source));
sad.setDisposable(source.subscribe(new CombineLatestObserver(observer, i, this._cb, state)));
}
return new NAryDisposable(subscriptions);
};
return CombineLatestObservable;
}(ObservableBase));
var CombineLatestObserver = (function (__super__) {
inherits(CombineLatestObserver, __super__);
function CombineLatestObserver(o, i, cb, state) {
this._o = o;
this._i = i;
this._cb = cb;
this._state = state;
__super__.call(this);
}
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
CombineLatestObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
if (this._state.hasValueAll || (this._state.hasValueAll = this._state.hasValue.every(identity))) {
var res = tryCatch(this._cb).apply(null, this._state.values);
if (res === errorObj) { return this._o.onError(res.e); }
this._o.onNext(res);
} else if (this._state.isDone.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
CombineLatestObserver.prototype.error = function (e) {
this._o.onError(e);
};
CombineLatestObserver.prototype.completed = function () {
this._state.isDone[this._i] = true;
this._state.isDone.every(identity) && this._o.onCompleted();
};
return CombineLatestObserver;
}(AbstractObserver));
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element.
*
* @example
* 1 - obs = Rx.Observable.combineLatest(obs1, obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
* 2 - obs = Rx.Observable.combineLatest([obs1, obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
var combineLatest = Observable.combineLatest = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
Array.isArray(args[0]) && (args = args[0]);
return new CombineLatestObservable(args, resultSelector);
};
================================================
FILE: src/core/perf/operators/concat.js
================================================
var ConcatObserver = (function(__super__) {
inherits(ConcatObserver, __super__);
function ConcatObserver(s, fn) {
this._s = s;
this._fn = fn;
__super__.call(this);
}
ConcatObserver.prototype.next = function (x) { this._s.o.onNext(x); };
ConcatObserver.prototype.error = function (e) { this._s.o.onError(e); };
ConcatObserver.prototype.completed = function () { this._s.i++; this._fn(this._s); };
return ConcatObserver;
}(AbstractObserver));
var ConcatObservable = (function(__super__) {
inherits(ConcatObservable, __super__);
function ConcatObservable(sources) {
this._sources = sources;
__super__.call(this);
}
function scheduleRecursive (state, recurse) {
if (state.disposable.isDisposed) { return; }
if (state.i === state.sources.length) { return state.o.onCompleted(); }
// Check if promise
var currentValue = state.sources[state.i];
isPromise(currentValue) && (currentValue = observableFromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new ConcatObserver(state, recurse)));
}
ConcatObservable.prototype.subscribeCore = function(o) {
var subscription = new SerialDisposable();
var disposable = disposableCreate(noop);
var state = {
o: o,
i: 0,
subscription: subscription,
disposable: disposable,
sources: this._sources
};
var cancelable = immediateScheduler.scheduleRecursive(state, scheduleRecursive);
return new NAryDisposable([subscription, disposable, cancelable]);
};
return ConcatObservable;
}(ObservableBase));
/**
* Concatenates all the observable sequences.
* @param {Array | Arguments} args Arguments or an array to concat to the observable sequence.
* @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
*/
var observableConcat = Observable.concat = function () {
var args;
if (Array.isArray(arguments[0])) {
args = arguments[0];
} else {
args = new Array(arguments.length);
for(var i = 0, len = arguments.length; i < len; i++) { args[i] = arguments[i]; }
}
return new ConcatObservable(args);
};
================================================
FILE: src/core/perf/operators/concatmap.js
================================================
observableProto.flatMapConcat = observableProto.concatMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(1);
};
================================================
FILE: src/core/perf/operators/distinctuntilchanged.js
================================================
var DistinctUntilChangedObservable = (function(__super__) {
inherits(DistinctUntilChangedObservable, __super__);
function DistinctUntilChangedObservable(source, keyFn, comparer) {
this.source = source;
this.keyFn = keyFn;
this.comparer = comparer;
__super__.call(this);
}
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this.keyFn, this.comparer));
};
return DistinctUntilChangedObservable;
}(ObservableBase));
var DistinctUntilChangedObserver = (function(__super__) {
inherits(DistinctUntilChangedObserver, __super__);
function DistinctUntilChangedObserver(o, keyFn, comparer) {
this.o = o;
this.keyFn = keyFn;
this.comparer = comparer;
this.hasCurrentKey = false;
this.currentKey = null;
__super__.call(this);
}
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x, comparerEquals;
if (isFunction(this.keyFn)) {
key = tryCatch(this.keyFn)(x);
if (key === errorObj) { return this.o.onError(key.e); }
}
if (this.hasCurrentKey) {
comparerEquals = tryCatch(this.comparer)(this.currentKey, key);
if (comparerEquals === errorObj) { return this.o.onError(comparerEquals.e); }
}
if (!this.hasCurrentKey || !comparerEquals) {
this.hasCurrentKey = true;
this.currentKey = key;
this.o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function(e) {
this.o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this.o.onCompleted();
};
return DistinctUntilChangedObserver;
}(AbstractObserver));
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
observableProto.distinctUntilChanged = function (keyFn, comparer) {
comparer || (comparer = defaultComparer);
return new DistinctUntilChangedObservable(this, keyFn, comparer);
};
================================================
FILE: src/core/perf/operators/empty.js
================================================
var EmptyObservable = (function(__super__) {
inherits(EmptyObservable, __super__);
function EmptyObservable(scheduler) {
this.scheduler = scheduler;
__super__.call(this);
}
EmptyObservable.prototype.subscribeCore = function (observer) {
var sink = new EmptySink(observer, this.scheduler);
return sink.run();
};
function EmptySink(observer, scheduler) {
this.observer = observer;
this.scheduler = scheduler;
}
function scheduleItem(s, state) {
state.onCompleted();
return disposableEmpty;
}
EmptySink.prototype.run = function () {
var state = this.observer;
return this.scheduler === immediateScheduler ?
scheduleItem(null, state) :
this.scheduler.schedule(state, scheduleItem);
};
return EmptyObservable;
}(ObservableBase));
var EMPTY_OBSERVABLE = new EmptyObservable(immediateScheduler);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
var observableEmpty = Observable.empty = function (scheduler) {
isScheduler(scheduler) || (scheduler = immediateScheduler);
return scheduler === immediateScheduler ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
================================================
FILE: src/core/perf/operators/filter.js
================================================
var FilterObservable = (function (__super__) {
inherits(FilterObservable, __super__);
function FilterObservable(source, predicate, thisArg) {
this.source = source;
this.predicate = bindCallback(predicate, thisArg, 3);
__super__.call(this);
}
FilterObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o, this.predicate, this));
};
function innerPredicate(predicate, self) {
return function(x, i, o) { return self.predicate(x, i, o) && predicate.call(this, x, i, o); }
}
FilterObservable.prototype.internalFilter = function(predicate, thisArg) {
return new FilterObservable(this.source, innerPredicate(predicate, this), thisArg);
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(o, predicate, source) {
this.o = o;
this.predicate = predicate;
this.source = source;
this.i = 0;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function(x) {
var shouldYield = tryCatch(this.predicate)(x, this.i++, this.source);
if (shouldYield === errorObj) {
return this.o.onError(shouldYield.e);
}
shouldYield && this.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.o.onError(e);
};
InnerObserver.prototype.completed = function () {
this.o.onCompleted();
};
return FilterObservable;
}(ObservableBase));
/**
* Filters the elements of an observable sequence based on a predicate by incorporating the element's index.
* @param {Function} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains elements from the input sequence that satisfy the condition.
*/
observableProto.filter = observableProto.where = function (predicate, thisArg) {
return this instanceof FilterObservable ? this.internalFilter(predicate, thisArg) :
new FilterObservable(this, predicate, thisArg);
};
================================================
FILE: src/core/perf/operators/finally.js
================================================
var FinallyObservable = (function (__super__) {
inherits(FinallyObservable, __super__);
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
__super__.call(this);
}
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
return FinallyObservable;
}(ObservableBase));
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
observableProto['finally'] = function (action, thisArg) {
return new FinallyObservable(this, action, thisArg);
};
================================================
FILE: src/core/perf/operators/flatmap.js
================================================
observableProto.flatMap = observableProto.selectMany = observableProto.mergeMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).mergeAll();
};
================================================
FILE: src/core/perf/operators/flatmapbase.js
================================================
var FlatMapObservable = Rx.FlatMapObservable = (function(__super__) {
inherits(FlatMapObservable, __super__);
function FlatMapObservable(source, selector, resultSelector, thisArg) {
this.resultSelector = isFunction(resultSelector) ? resultSelector : null;
this.selector = bindCallback(isFunction(selector) ? selector : function() { return selector; }, thisArg, 3);
this.source = source;
__super__.call(this);
}
FlatMapObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new InnerObserver(o, this.selector, this.resultSelector, this));
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(observer, selector, resultSelector, source) {
this.i = 0;
this.selector = selector;
this.resultSelector = resultSelector;
this.source = source;
this.o = observer;
AbstractObserver.call(this);
}
InnerObserver.prototype._wrapResult = function(result, x, i) {
return this.resultSelector ?
result.map(function(y, i2) { return this.resultSelector(x, y, i, i2); }, this) :
result;
};
InnerObserver.prototype.next = function(x) {
var i = this.i++;
var result = tryCatch(this.selector)(x, i, this.source);
if (result === errorObj) { return this.o.onError(result.e); }
isPromise(result) && (result = observableFromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = Observable.from(result));
this.o.onNext(this._wrapResult(result, x, i));
};
InnerObserver.prototype.error = function(e) { this.o.onError(e); };
InnerObserver.prototype.completed = function() { this.o.onCompleted(); };
return FlatMapObservable;
}(ObservableBase));
================================================
FILE: src/core/perf/operators/flatmapfirst.js
================================================
observableProto.flatMapFirst = observableProto.exhaustMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchFirst();
};
================================================
FILE: src/core/perf/operators/flatmaplatest.js
================================================
observableProto.flatMapLatest = observableProto.switchMap = function(selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).switchLatest();
};
================================================
FILE: src/core/perf/operators/flatmapwithmaxconcurrent.js
================================================
observableProto.flatMapWithMaxConcurrent = observableProto.flatMapMaxConcurrent = function(limit, selector, resultSelector, thisArg) {
return new FlatMapObservable(this, selector, resultSelector, thisArg).merge(limit);
};
================================================
FILE: src/core/perf/operators/from.js
================================================
var FromObservable = (function(__super__) {
inherits(FromObservable, __super__);
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
__super__.call(this);
}
function createScheduleMethod(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) { return o.onError(next.e); }
if (next.done) { return o.onCompleted(); }
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) { return o.onError(result.e); }
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, createScheduleMethod(o, it, this._fn));
};
return FromObservable;
}(ObservableBase));
var maxSafeInteger = Math.pow(2, 53) - 1;
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function numberIsFinite(value) {
return typeof value === 'number' && root.isFinite(value);
}
function isNan(n) {
return n !== n;
}
function getIterable(o) {
var i = o[$iterator$], it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) { throw new TypeError('Object is not iterable'); }
return o[$iterator$]();
}
function sign(value) {
var number = +value;
if (number === 0) { return number; }
if (isNaN(number)) { return number; }
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) { return 0; }
if (len === 0 || !numberIsFinite(len)) { return len; }
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) { return 0; }
if (len > maxSafeInteger) { return maxSafeInteger; }
return len;
}
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
var observableFrom = Observable.from = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.')
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
if (mapFn) {
var mapper = bindCallback(mapFn, thisArg, 2);
}
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromObservable(iterable, mapper, scheduler);
}
================================================
FILE: src/core/perf/operators/fromarray.js
================================================
/**
* Converts an array to an observable sequence, using an optional scheduler to enumerate the array.
* @deprecated use Observable.from or Observable.of
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence.
*/
var observableFromArray = Observable.fromArray = function (array, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler)
};
================================================
FILE: src/core/perf/operators/fromarrayobservable.js
================================================
var FromArrayObservable = (function(__super__) {
inherits(FromArrayObservable, __super__);
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, args) {
var len = args.length;
return function loopRecursive (i, recurse) {
if (i < len) {
o.onNext(args[i]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
FromArrayObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._args));
};
return FromArrayObservable;
}(ObservableBase));
================================================
FILE: src/core/perf/operators/fromcallback.js
================================================
function createCbObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createCbHandler(o, ctx, selector));
fn.apply(ctx, args);
return o.asObservable();
}
function createCbHandler(o, ctx, selector) {
return function handler () {
var len = arguments.length, results = new Array(len);
for(var i = 0; i < len; i++) { results[i] = arguments[i]; }
if (isFunction(selector)) {
results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) { return o.onError(results.e); }
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
/**
* Converts a callback function to an observable sequence.
*
* @param {Function} fn Function with a callback as the last parameter to convert to an Observable sequence.
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next.
* @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array.
*/
Observable.fromCallback = function (fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length, args = new Array(len)
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return createCbObservable(fn, ctx, selector, args);
};
};
================================================
FILE: src/core/perf/operators/fromnodecallback.js
================================================
function createNodeObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createNodeHandler(o, ctx, selector));
fn.apply(ctx, args);
return o.asObservable();
}
function createNodeHandler(o, ctx, selector) {
return function handler () {
var err = arguments[0];
if (err) { return o.onError(err); }
var len = arguments.length, results = [];
for(var i = 1; i < len; i++) { results[i - 1] = arguments[i]; }
if (isFunction(selector)) {
var results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) { return o.onError(results.e); }
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
/**
* Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
* @param {Function} fn The function to call
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
* @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
*/
Observable.fromNodeCallback = function (fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return createNodeObservable(fn, ctx, selector, args);
};
};
================================================
FILE: src/core/perf/operators/frompromise.js
================================================
var FromPromiseObservable = (function(__super__) {
inherits(FromPromiseObservable, __super__);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
__super__.call(this);
}
function scheduleNext(s, state) {
var o = state[0], data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0], err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function(o) {
var sad = new SingleAssignmentDisposable(), self = this, p = this._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p
.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
return FromPromiseObservable;
}(ObservableBase));
/**
* Converts a Promise to an Observable sequence
* @param {Promise} An ES6 Compliant promise.
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
var observableFromPromise = Observable.fromPromise = function (promise, scheduler) {
scheduler || (scheduler = defaultScheduler);
return new FromPromiseObservable(promise, scheduler);
};
================================================
FILE: src/core/perf/operators/ignoreelements.js
================================================
var IgnoreElementsObservable = (function(__super__) {
inherits(IgnoreElementsObservable, __super__);
function IgnoreElementsObservable(source) {
this.source = source;
__super__.call(this);
}
IgnoreElementsObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new InnerObserver(o));
};
function InnerObserver(o) {
this.o = o;
this.isStopped = false;
}
InnerObserver.prototype.onNext = noop;
InnerObserver.prototype.onError = function (err) {
if(!this.isStopped) {
this.isStopped = true;
this.o.onError(err);
}
};
InnerObserver.prototype.onCompleted = function () {
if(!this.isStopped) {
this.isStopped = true;
this.o.onCompleted();
}
};
InnerObserver.prototype.dispose = function() { this.isStopped = true; };
InnerObserver.prototype.fail = function (e) {
if (!this.isStopped) {
this.isStopped = true;
this.observer.onError(e);
return true;
}
return false;
};
return IgnoreElementsObservable;
}(ObservableBase));
/**
* Ignores all elements in an observable sequence leaving only the termination messages.
* @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence.
*/
observableProto.ignoreElements = function () {
return new IgnoreElementsObservable(this);
};
================================================
FILE: src/core/perf/operators/just.js
================================================
var JustObservable = (function(__super__) {
inherits(JustObservable, __super__);
function JustObservable(value, scheduler) {
this._value = value;
this._scheduler = scheduler;
__super__.call(this);
}
JustObservable.prototype.subscribeCore = function (o) {
var state = [this._value, o];
return this._scheduler === immediateScheduler ?
scheduleItem(null, state) :
this._scheduler.schedule(state, scheduleItem);
};
function scheduleItem(s, state) {
var value = state[0], observer = state[1];
observer.onNext(value);
observer.onCompleted();
return disposableEmpty;
}
return JustObservable;
}(ObservableBase));
/**
* Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages.
* There is an alias called 'just' or browsers 0) {
this.parent.handleSubscribe(this.parent.q.shift());
} else {
this.parent.activeCount--;
this.parent.done && this.parent.activeCount === 0 && this.parent.o.onCompleted();
}
};
return MergeObserver;
}(AbstractObserver));
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
observableProto.merge = function (maxConcurrentOrOther) {
return typeof maxConcurrentOrOther !== 'number' ?
observableMerge(this, maxConcurrentOrOther) :
new MergeObservable(this, maxConcurrentOrOther);
};
================================================
FILE: src/core/perf/operators/never.js
================================================
var NeverObservable = (function(__super__) {
inherits(NeverObservable, __super__);
function NeverObservable() {
__super__.call(this);
}
NeverObservable.prototype.subscribeCore = function (observer) {
return disposableEmpty;
};
return NeverObservable;
}(ObservableBase));
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
var observableNever = Observable.never = function () {
return NEVER_OBSERVABLE;
};
================================================
FILE: src/core/perf/operators/of.js
================================================
function observableOf (scheduler, array) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new FromArrayObservable(array, scheduler);
}
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.of = function () {
var len = arguments.length, args = new Array(len);
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
return new FromArrayObservable(args, currentThreadScheduler);
};
/**
* This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments.
* @param {Scheduler} scheduler A scheduler to use for scheduling the arguments.
* @returns {Observable} The observable sequence whose elements are pulled from the given arguments.
*/
Observable.ofWithScheduler = function (scheduler) {
var len = arguments.length, args = new Array(len - 1);
for(var i = 1; i < len; i++) { args[i - 1] = arguments[i]; }
return new FromArrayObservable(args, scheduler);
};
================================================
FILE: src/core/perf/operators/pairs.js
================================================
var PairsObservable = (function(__super__) {
inherits(PairsObservable, __super__);
function PairsObservable(o, scheduler) {
this._o = o;
this._keys = Object.keys(o);
this._scheduler = scheduler;
__super__.call(this);
}
function scheduleMethod(o, obj, keys) {
return function loopRecursive(i, recurse) {
if (i < keys.length) {
var key = keys[i];
o.onNext([key, obj[key]]);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
PairsObservable.prototype.subscribeCore = function (o) {
return this._scheduler.scheduleRecursive(0, scheduleMethod(o, this._o, this._keys));
};
return PairsObservable;
}(ObservableBase));
/**
* Convert an object into an observable sequence of [key, value] pairs.
* @param {Object} obj The object to inspect.
* @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on.
* @returns {Observable} An observable sequence of [key, value] pairs from the object.
*/
Observable.pairs = function (obj, scheduler) {
scheduler || (scheduler = currentThreadScheduler);
return new PairsObservable(obj, scheduler);
};
================================================
FILE: src/core/perf/operators/range.js
================================================
var RangeObservable = (function(__super__) {
inherits(RangeObservable, __super__);
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
__super__.call(this);
}
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
return RangeObservable;
}(ObservableBase));
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
Observable.range = function (start, count, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RangeObservable(start, count, scheduler);
};
================================================
FILE: src/core/perf/operators/reduce.js
================================================
var ReduceObservable = (function(__super__) {
inherits(ReduceObservable, __super__);
function ReduceObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ReduceObservable.prototype.subscribeCore = function(observer) {
return this.source.subscribe(new ReduceObserver(observer,this));
};
return ReduceObservable;
}(ObservableBase));
var ReduceObserver = (function (__super__) {
inherits(ReduceObserver, __super__);
function ReduceObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ReduceObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._i++;
};
ReduceObserver.prototype.error = function (e) {
this._o.onError(e);
};
ReduceObserver.prototype.completed = function () {
this._hv && this._o.onNext(this._a);
!this._hv && this._hs && this._o.onNext(this._s);
!this._hv && !this._hs && this._o.onError(new EmptyError());
this._o.onCompleted();
};
return ReduceObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
* For aggregation behavior with incremental intermediate results, see Observable.scan.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @param {Any} [seed] The initial accumulator value.
* @returns {Observable} An observable sequence containing a single element with the final accumulator value.
*/
observableProto.reduce = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ReduceObservable(this, accumulator, hasSeed, seed);
};
================================================
FILE: src/core/perf/operators/repeat.js
================================================
var RepeatObservable = (function(__super__) {
inherits(RepeatObservable, __super__);
function RepeatObservable(value, repeatCount, scheduler) {
this.value = value;
this.repeatCount = repeatCount == null ? -1 : repeatCount;
this.scheduler = scheduler;
__super__.call(this);
}
RepeatObservable.prototype.subscribeCore = function (observer) {
var sink = new RepeatSink(observer, this);
return sink.run();
};
return RepeatObservable;
}(ObservableBase));
function RepeatSink(observer, parent) {
this.observer = observer;
this.parent = parent;
}
RepeatSink.prototype.run = function () {
var observer = this.observer, value = this.parent.value;
function loopRecursive(i, recurse) {
if (i === -1 || i > 0) {
observer.onNext(value);
i > 0 && i--;
}
if (i === 0) { return observer.onCompleted(); }
recurse(i);
}
return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount, loopRecursive);
};
/**
* Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages.
* @param {Mixed} value Element to repeat.
* @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely.
* @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate.
* @returns {Observable} An observable sequence that repeats the given element the specified number of times.
*/
Observable.repeat = function (value, repeatCount, scheduler) {
isScheduler(scheduler) || (scheduler = currentThreadScheduler);
return new RepeatObservable(value, repeatCount, scheduler);
};
================================================
FILE: src/core/perf/operators/scan.js
================================================
var ScanObservable = (function(__super__) {
inherits(ScanObservable, __super__);
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
__super__.call(this);
}
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
return ScanObservable;
}(ObservableBase));
var ScanObserver = (function (__super__) {
inherits(ScanObserver, __super__);
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
__super__.call(this);
}
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
return ScanObserver;
}(AbstractObserver));
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
observableProto.scan = function () {
var hasSeed = false, seed, accumulator = arguments[0];
if (arguments.length === 2) {
hasSeed = true;
seed = arguments[1];
}
return new ScanObservable(this, accumulator, hasSeed, seed);
};
================================================
FILE: src/core/perf/operators/skip.js
================================================
var SkipObservable = (function(__super__) {
inherits(SkipObservable, __super__);
function SkipObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
function SkipObserver(o, c) {
this._o = o;
this._r = c;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
return SkipObservable;
}(ObservableBase));
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
observableProto.skip = function (count) {
if (count < 0) { throw new ArgumentOutOfRangeError(); }
return new SkipObservable(this, count);
};
================================================
FILE: src/core/perf/operators/skipuntil.js
================================================
var SkipUntilObservable = (function(__super__) {
inherits(SkipUntilObservable, __super__);
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? observableFromPromise(other) : other;
this._open = false;
__super__.call(this);
}
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = observableFromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
return SkipUntilObservable;
}(ObservableBase));
var SkipUntilSourceObserver = (function(__super__) {
inherits(SkipUntilSourceObserver, __super__);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
__super__.call(this);
}
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
return SkipUntilSourceObserver;
}(AbstractObserver));
var SkipUntilOtherObserver = (function(__super__) {
inherits(SkipUntilOtherObserver, __super__);
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
__super__.call(this);
}
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;
this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
return SkipUntilOtherObserver;
}(AbstractObserver));
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
observableProto.skipUntil = function (other) {
return new SkipUntilObservable(this, other);
};
================================================
FILE: src/core/perf/operators/switch.js
================================================
var SwitchObservable = (function(__super__) {
inherits(SwitchObservable, __super__);
function SwitchObservable(source) {
this.source = source;
__super__.call(this);
}
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
inherits(SwitchObserver, AbstractObserver);
function SwitchObserver(o, inner) {
this.o = o;
this.inner = inner;
this.stopped = false;
this.latest = 0;
this.hasLatest = false;
AbstractObserver.call(this);
}
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this.latest;
this.hasLatest = true;
this.inner.setDisposable(d);
isPromise(innerSource) && (innerSource = observableFromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this.o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this.stopped = true;
!this.hasLatest && this.o.onCompleted();
};
inherits(InnerObserver, AbstractObserver);
function InnerObserver(parent, id) {
this.parent = parent;
this.id = id;
AbstractObserver.call(this);
}
InnerObserver.prototype.next = function (x) {
this.parent.latest === this.id && this.parent.o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this.parent.latest === this.id && this.parent.o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this.parent.latest === this.id) {
this.parent.hasLatest = false;
this.parent.stopped && this.parent.o.onCompleted();
}
};
return SwitchObservable;
}(ObservableBase));
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
observableProto['switch'] = observableProto.switchLatest = function () {
return new SwitchObservable(this);
};
================================================
FILE: src/core/perf/operators/take.js
================================================
var TakeObservable = (function(__super__) {
inherits(TakeObservable, __super__);
function TakeObservable(source, count) {
this.source = source;
this._count = count;
__super__.call(this);
}
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
return TakeObservable;
}(ObservableBase));
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
var item = CurrentThreadScheduler.queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!CurrentThreadScheduler.queue) {
CurrentThreadScheduler.queue = new PriorityQueue(4);
CurrentThreadScheduler.queue.enqueue(si);
var result = tryCatch(runTrampoline)();
CurrentThreadScheduler.queue = null;
if (result === errorObj) {
thrower(result.e);
}
} else {
CurrentThreadScheduler.queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () {
return !CurrentThreadScheduler.queue;
};
module.exports = CurrentThreadScheduler;
/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(13);
var SingleAssignmentDisposable = __webpack_require__(17);
var cmp = __webpack_require__(18);
function ScheduledItem(scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || cmp;
this.disposable = new SingleAssignmentDisposable();
}
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return Disposable._fixup(this.action(this.scheduler, this.state));
};
module.exports = ScheduledItem;
/***/ },
/* 17 */
/***/ function(module, exports) {
'use strict';
function SingleAssignmentDisposable() {
this.isDisposed = false;
this._current = null;
}
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this._current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this._current) {
throw new Error('Disposable has already been assigned');
}
var shouldDispose = this.isDisposed;
!shouldDispose && (this._current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this._current;
this._current = null;
old && old.dispose();
}
};
module.exports = SingleAssignmentDisposable;
/***/ },
/* 18 */
/***/ function(module, exports) {
'use strict';
module.exports = function comparer(x, y) {
if (x > y) {
return 1;
}
if (y > x) {
return -1;
}
return 0;
};
/***/ },
/* 19 */
/***/ function(module, exports) {
'use strict';
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
function PriorityQueue(capacity) {
this.items = new Array(capacity);
this.length = 0;
}
PriorityQueue.prototype.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
PriorityQueue.prototype.percolate = function (index) {
if (index >= this.length || index < 0) {
return;
}
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) {
return;
}
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
PriorityQueue.prototype.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) {
return;
}
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
PriorityQueue.prototype.peek = function () {
return this.items[0].value;
};
PriorityQueue.prototype.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
PriorityQueue.prototype.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
PriorityQueue.prototype.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
PriorityQueue.prototype.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
module.exports = PriorityQueue;
/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isFunction = __webpack_require__(9);
var errorObj = module.exports.errorObj = { e: {} };
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
module.exports.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) {
throw new TypeError('fn must be a function');
}
return tryCatcherGen(fn);
};
module.exports.thrower = function thrower(e) {
throw e;
};
/***/ },
/* 21 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Scheduler = __webpack_require__(12);
var Disposable = __webpack_require__(13);
var inherits = __webpack_require__(6);
function ImmediateScheduler() {
Scheduler.call(this);
}
inherits(ImmediateScheduler, Scheduler);
ImmediateScheduler.prototype.schedule = function (state, action) {
return Disposable._fixup(action(this, state));
};
module.exports = ImmediateScheduler;
/***/ },
/* 22 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global, process) {'use strict';
var Disposable = __webpack_require__(13);
var BinaryDisposable = __webpack_require__(24);
var SingleAssignmentDisposable = __webpack_require__(17);
var Scheduler = __webpack_require__(12);
var isFunction = __webpack_require__(9);
var noop = __webpack_require__(3);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
var inherits = __webpack_require__(6);
var scheduleMethod, clearMethod;
(function () {
var nextHandle = 1,
tasksByHandle = {},
currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
global.setTimeout(function () {
runTask(handle);
}, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) {
thrower(result.e);
}
}
}
}
var setImmediate = global.setImmediate;
function postMessageSupported() {
// Ensure not in a worker
if (!global.postMessage || global.importScripts) {
return false;
}
var isAsync = false,
oldHandler = global.onmessage;
// Test for async
global.onmessage = function () {
isAsync = true;
};
global.postMessage('', '*');
global.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () {
runTask(id);
});
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () {
runTask(id);
});
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
global.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
global.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!global.MessageChannel) {
var channel = new global.MessageChannel();
channel.port1.onmessage = function (e) {
runTask(e.data);
};
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = global.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
global.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
global.setTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
})();
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
function DefaultScheduler() {
Scheduler.call(this);
}
inherits(DefaultScheduler, Scheduler);
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(method, id) {
this._id = id;
this._method = method;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._method.call(null, this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(clearMethod, id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) {
return this.schedule(state, action);
}
var disposable = new SingleAssignmentDisposable(),
id = global.setTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new ClearDisposable(global.clearTimeout, id));
};
module.exports = DefaultScheduler;
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(23)))
/***/ },
/* 23 */
/***/ function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = setTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
clearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
setTimeout(drainQueue, 0);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ },
/* 24 */
/***/ function(module, exports) {
'use strict';
function BinaryDisposable(first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
}
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
module.exports = BinaryDisposable;
/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Scheduler = __webpack_require__(12);
var Disposable = __webpack_require__(13);
var SingleAssignmentDisposable = __webpack_require__(17);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
Scheduler.call(this);
}
inherits(CatchScheduler, Scheduler);
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () {
return this._scheduler.now();
};
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) {
thrower(res.e);
}
return Disposable.empty;
}
return Disposable._fixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this,
failed = false,
d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) {
return null;
}
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) {
thrower(res.e);
}
d.dispose();
return null;
}
return res;
}));
return d;
};
module.exports = CatchScheduler;
/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var SingleAssignmentDisposable = __webpack_require__(17);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function AutoDetachObserver(observer) {
AbstractObserver.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
inherits(AutoDetachObserver, AbstractObserver);
AutoDetachObserver.prototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserver.prototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserver.prototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserver.prototype.setDisposable = function (value) {
this.m.setDisposable(value);
};
AutoDetachObserver.prototype.getDisposable = function () {
return this.m.getDisposable();
};
AutoDetachObserver.prototype.dispose = function () {
AbstractObserver.prototype.dispose.call(this);
this.m.dispose();
};
module.exports = AutoDetachObserver;
/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var Scheduler = __webpack_require__(12);
var SingleAssignmentDisposable = __webpack_require__(17);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
ObservableBase.call(this);
}
inherits(FromPromiseObservable, ObservableBase);
function scheduleNext(s, state) {
var o = state[0],
data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0],
err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function (o) {
var sad = new SingleAssignmentDisposable(),
self = this,
p = self._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
/**
* Converts a Promise to an Observable sequence
* @param {Promise|Function} An ES6 Compliant promise or a function that returns one
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
module.exports = function fromPromise(promise, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return new FromPromiseObservable(promise, scheduler);
};
/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isFunction = __webpack_require__(9);
module.exports = function isPromise(p) {
return p && isFunction(p.then);
};
/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var Disposable = __webpack_require__(13);
var inherits = __webpack_require__(6);
function NeverObservable() {
ObservableBase.call(this);
}
inherits(NeverObservable, ObservableBase);
NeverObservable.prototype.subscribeCore = function () {
return Disposable.empty;
};
var NEVER_OBSERVABLE = new NeverObservable();
/**
* Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
* @returns {Observable} An observable sequence whose observers will never get called.
*/
module.exports = function never() {
return NEVER_OBSERVABLE;
};
/***/ },
/* 30 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AsyncSubject = __webpack_require__(31);
var asObservable = __webpack_require__(35);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function createCbHandler(o, ctx, selector) {
return function handler() {
var len = arguments.length,
results = new Array(len);
for (var i = 0; i < len; i++) {
results[i] = arguments[i];
}
if (isFunction(selector)) {
results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) {
return o.onError(results.e);
}
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
function createCbObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createCbHandler(o, ctx, selector));
var res = tryCatch(fn).apply(ctx, args);
if (res === errorObj) {
o.onError(res.e);
}
return asObservable(o);
}
/**
* Converts a callback function to an observable sequence.
*
* @param {Function} fn Function with a callback as the last parameter to convert to an Observable sequence.
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next.
* @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array.
*/
module.exports = function bindCallback(fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return createCbObservable(fn, ctx, selector, args);
};
};
/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(13);
var Observable = __webpack_require__(8);
var Observer = __webpack_require__(1);
var InnerSubscription = __webpack_require__(32);
var addProperties = __webpack_require__(33);
var cloneArray = __webpack_require__(34);
var inherits = __webpack_require__(6);
/**
* Represents the result of an asynchronous operation.
* The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
*/
function AsyncSubject() {
Observable.call(this);
this.isDisposed = false;
this.isStopped = false;
this.hasValue = false;
this.observers = [];
this.hasError = false;
}
inherits(AsyncSubject, Observable);
addProperties(AsyncSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else if (this.hasValue) {
o.onNext(this.value);
o.onCompleted();
} else {
o.onCompleted();
}
return Disposable.empty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () {
Disposable.checkDisposed(this);
return this.observers.length > 0;
},
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i;
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers),
len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
module.exports = AsyncSubject;
/***/ },
/* 32 */
/***/ function(module, exports) {
'use strict';
function InnerSubscription(s, o) {
this._s = s;
this._o = o;
}
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
module.exports = InnerSubscription;
/***/ },
/* 33 */
/***/ function(module, exports) {
'use strict';
module.exports = function addProperties() {
var obj = arguments[0];
for (var sources = [], i = 1, len = arguments.length; i < len; i++) {
sources.push(arguments[i]);
}
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
/***/ },
/* 34 */
/***/ function(module, exports) {
'use strict';
module.exports = function cloneArray(arr) {
var len = arr.length,
a = new Array(len);
for (var i = 0; i < len; i++) {
a[i] = arr[i];
}
return a;
};
/***/ },
/* 35 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AnonymousObservable = __webpack_require__(36);
function createAsObservable(source) {
return function subscribe(o) {
return source.subscribe(o);
};
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
module.exports = function asObservable(source) {
return new AnonymousObservable(createAsObservable(source), source);
};
/***/ },
/* 36 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var inherits = __webpack_require__(6);
var isFunction = __webpack_require__(9);
var Observable = __webpack_require__(8);
var Disposable = __webpack_require__(13);
var AutoDetachObserver = __webpack_require__(26);
var Scheduler = __webpack_require__(12);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber : isFunction(subscriber) ? Disposable.create(subscriber) : Disposable.empty;
}
function setDisposable(s, state) {
var ado = state[0],
self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(sub.e)) {
thrower(sub.e);
}
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
Observable.call(this);
}
inherits(AnonymousObservable, Observable);
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o),
state = [ado, this];
if (Scheduler.queue.scheduleRequired()) {
Scheduler.queue.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
module.exports = AnonymousObservable;
/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AsyncSubject = __webpack_require__(31);
var asObservable = __webpack_require__(35);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function createNodeHandler(o, ctx, selector) {
return function handler() {
var err = arguments[0];
if (err) {
return o.onError(err);
}
var len = arguments.length,
results = [];
for (var i = 1; i < len; i++) {
results[i - 1] = arguments[i];
}
if (isFunction(selector)) {
results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) {
return o.onError(results.e);
}
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
function createNodeObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createNodeHandler(o, ctx, selector));
var res = tryCatch(fn).apply(ctx, args);
if (res === errorObj) {
o.onError(res.e);
}
return asObservable(o);
}
/**
* Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
* @param {Function} fn The function to call
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
* @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
*/
module.exports = function bindNodeCallback(fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return createNodeObservable(fn, ctx, selector, args);
};
};
/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var defer = __webpack_require__(39);
var empty = __webpack_require__(41);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var isScheduler = __webpack_require__(12).isScheduler;
function createCase(selector, sources, defaultSourceOrScheduler) {
return function () {
isPromise(defaultSourceOrScheduler) && (defaultSourceOrScheduler = fromPromise(defaultSourceOrScheduler));
defaultSourceOrScheduler || (defaultSourceOrScheduler = empty());
isScheduler(defaultSourceOrScheduler) && (defaultSourceOrScheduler = empty(defaultSourceOrScheduler));
var result = sources[selector()];
isPromise(result) && (result = fromPromise(result));
return result || defaultSourceOrScheduler;
};
}
/**
* Uses selector to determine which source in sources to use.
* @param {Function} selector The function which extracts the value for to test in a case statement.
* @param {Array} sources A object which has keys which correspond to the case statement labels.
* @param {Observable} [elseSource] The observable sequence or Promise that will be run if the sources are not matched. If this is not provided, it defaults to Rx.Observabe.empty with the specified scheduler.
*
* @returns {Observable} An observable sequence which is determined by a case statement.
*/
module.exports = function case_(selector, sources, defaultSourceOrScheduler) {
return defer(createCase(selector, sources, defaultSourceOrScheduler));
};
/***/ },
/* 39 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var fromPromise = __webpack_require__(27);
var throwError = __webpack_require__(40);
var isPromise = __webpack_require__(28);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function Defer(factory) {
this._f = factory;
ObservableBase.call(this);
}
inherits(Defer, ObservableBase);
Defer.prototype.subscribeCore = function (o) {
var result = tryCatch(this._f)();
if (result === errorObj) {
return throwError(result.e).subscribe(o);
}
isPromise(result) && (result = fromPromise(result));
return result.subscribe(o);
};
/**
* Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes.
*
* @example
* var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); });
* @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise.
* @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function.
*/
module.exports = function observableDefer(observableFactory) {
return new Defer(observableFactory);
};
/***/ },
/* 40 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var Disposable = __webpack_require__(13);
var Scheduler = __webpack_require__(12);
var inherits = __webpack_require__(6);
function scheduleItem(s, state) {
var e = state[0],
o = state[1];
o.onError(e);
return Disposable.empty;
}
function ThrowObservable(error, scheduler) {
this._error = error;
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(ThrowObservable, ObservableBase);
ThrowObservable.prototype.subscribeCore = function (o) {
var state = [this._error, o];
return this._scheduler === Scheduler.immediate ? scheduleItem(null, state) : this._scheduler.schedule(state, scheduleItem);
};
module.exports = function throwError(error, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.immediate);
return new ThrowObservable(error, scheduler);
};
/***/ },
/* 41 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var Disposable = __webpack_require__(13);
var Scheduler = __webpack_require__(12);
var inherits = __webpack_require__(6);
function scheduleItem(s, state) {
state.onCompleted();
return Disposable.empty;
}
function EmptyObservable(scheduler) {
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(EmptyObservable, ObservableBase);
EmptyObservable.prototype.subscribeCore = function (o) {
return this.scheduler === Scheduler.immediate ? scheduleItem(null, o) : this._scheduler.schedule(o, scheduleItem);
};
var EMPTY_OBSERVABLE = new EmptyObservable(Scheduler.immediate);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
module.exports = function empty(scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.immediate);
return scheduler === Scheduler.immediate ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
/***/ },
/* 42 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var Scheduler = __webpack_require__(12);
var NAryDisposable = __webpack_require__(43);
var SerialDisposable = __webpack_require__(44);
var SingleAssignmentDisposable = __webpack_require__(17);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var inherits = __webpack_require__(6);
function CatchObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(CatchObserver, AbstractObserver);
CatchObserver.prototype.next = function (x) {
this._state.o.onNext(x);
};
CatchObserver.prototype.error = function (e) {
this._state.lastError = e;this._recurse(this._state);
};
CatchObserver.prototype.completed = function () {
this._state.o.onCompleted();
};
function CatchObservable(sources) {
this.sources = sources;
ObservableBase.call(this);
}
inherits(CatchObservable, ObservableBase);
function scheduleMethod(state, recurse) {
if (state.isDisposed) {
return;
}
if (state.i < state.sources.length) {
var currentValue = state.sources[state.i++];
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new CatchObserver(state, recurse)));
} else {
if (state.lastError !== null) {
state.o.onError(state.lastError);
} else {
state.o.onCompleted();
}
}
}
function IsDisposedDisposable(s) {
this._s = s;
}
IsDisposedDisposable.prototype.dispose = function () {
!this._s.isDisposed && (this._s.isDisposed = true);
};
CatchObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
sources: this.sources,
i: 0,
subscription: subscription,
lastError: null,
o: o
};
var cancelable = Scheduler.queue.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
module.exports = function catch_() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return new CatchObservable(args);
};
/***/ },
/* 43 */
/***/ function(module, exports) {
'use strict';
function NAryDisposable(disposables) {
this._disposables = disposables;
this.isDisposed = false;
}
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
module.exports = NAryDisposable;
/***/ },
/* 44 */
/***/ function(module, exports) {
'use strict';
function SerialDisposable() {
this.isDisposed = false;
this._current = null;
}
SerialDisposable.prototype.getDisposable = function () {
return this._current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this._current;
this._current = value;
old && old.dispose();
}
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this._current;
this._current = null;
old && old.dispose();
}
};
module.exports = SerialDisposable;
/***/ },
/* 45 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var SingleAssignmentDisposable = __webpack_require__(17);
var NAryDisposable = __webpack_require__(43);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var identity = __webpack_require__(46);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function falseFactory() {
return false;
}
function initializeArray(n, fn) {
var results = new Array(n);
for (var i = 0; i < n; i++) {
results[i] = fn(i);
}
return results;
}
function argumentsToArray() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return args;
}
function CombineLatestObserver(o, i, cb, state) {
this._o = o;
this._i = i;
this._cb = cb;
this._state = state;
AbstractObserver.call(this);
}
inherits(CombineLatestObserver, AbstractObserver);
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
CombineLatestObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
if (this._state.hasValueAll || (this._state.hasValueAll = this._state.hasValue.every(identity))) {
var res = tryCatch(this._cb).apply(null, this._state.values);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onNext(res);
} else if (this._state.isDone.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
CombineLatestObserver.prototype.error = function (e) {
this._o.onError(e);
};
CombineLatestObserver.prototype.completed = function () {
this._state.isDone[this._i] = true;
this._state.isDone.every(identity) && this._o.onCompleted();
};
function CombineLatestObservable(params, cb) {
this._params = params;
this._cb = cb;
ObservableBase.call(this);
}
inherits(CombineLatestObservable, ObservableBase);
CombineLatestObservable.prototype.subscribeCore = function (observer) {
var len = this._params.length,
subscriptions = new Array(len);
var state = {
hasValue: initializeArray(len, falseFactory),
hasValueAll: false,
isDone: initializeArray(len, falseFactory),
values: new Array(len)
};
for (var i = 0; i < len; i++) {
var source = this._params[i],
sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = fromPromise(source));
sad.setDisposable(source.subscribe(new CombineLatestObserver(observer, i, this._cb, state)));
}
return new NAryDisposable(subscriptions);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element.
*
* @example
* 1 - obs = Rx.Observable.combineLatest(obs1, obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
* 2 - obs = Rx.Observable.combineLatest([obs1, obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
module.exports = function combineLatest() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
return new CombineLatestObservable(args, resultSelector);
};
/***/ },
/* 46 */
/***/ function(module, exports) {
'use strict';
module.exports = function identity(x) {
return x;
};
/***/ },
/* 47 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var Scheduler = __webpack_require__(12);
var Disposable = __webpack_require__(13);
var NAryDisposable = __webpack_require__(43);
var SerialDisposable = __webpack_require__(44);
var SingleAssignmentDisposable = __webpack_require__(17);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var inherits = __webpack_require__(6);
function ConcatObserver(s, fn) {
this._s = s;
this._fn = fn;
AbstractObserver.call(this);
}
inherits(ConcatObserver, AbstractObserver);
ConcatObserver.prototype.next = function (x) {
this._s.o.onNext(x);
};
ConcatObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ConcatObserver.prototype.completed = function () {
this._s.i++;this._fn(this._s);
};
function ConcatObservable(sources) {
this._sources = sources;
ObservableBase.call(this);
}
inherits(ConcatObservable, ObservableBase);
function scheduleRecursive(state, recurse) {
if (state.disposable.isDisposed) {
return;
}
if (state.i === state.sources.length) {
return state.o.onCompleted();
}
// Check if promise
var currentValue = state.sources[state.i];
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new ConcatObserver(state, recurse)));
}
ConcatObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var disposable = Disposable.create();
var state = {
o: o,
i: 0,
subscription: subscription,
disposable: disposable,
sources: this._sources
};
var cancelable = Scheduler.immediate.scheduleRecursive(state, scheduleRecursive);
return new NAryDisposable([subscription, disposable, cancelable]);
};
/**
* Concatenates all the observable sequences.
* @param {Array | Arguments} args Arguments or an array to concat to the observable sequence.
* @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
*/
module.exports = function concat() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return new ConcatObservable(args);
};
/***/ },
/* 48 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AnonymousObservable = __webpack_require__(36);
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
module.exports = function create(subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var CompositeDisposable = __webpack_require__(14);
var Disposable = __webpack_require__(13);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function argumentsToArray() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return args;
}
function ForkJoinObserver(o, s, i, cb, subs) {
this._o = o;
this._s = s;
this._i = i;
this._cb = cb;
this._subs = subs;
AbstractObserver.call(this);
}
inherits(ForkJoinObserver, AbstractObserver);
ForkJoinObserver.prototype.next = function (x) {
if (!this._s.finished) {
this._s.hasResults[this._i] = true;
this._s.results[this._i] = x;
}
};
ForkJoinObserver.prototype.error = function (e) {
this._s.finished = true;
this._o.onError(e);
this._subs.dispose();
};
ForkJoinObserver.prototype.completed = function () {
if (!this._s.finished) {
if (!this._s.hasResults[this._i]) {
return this._o.onCompleted();
}
this._s.hasCompleted[this._i] = true;
for (var i = 0; i < this._s.results.length; i++) {
if (!this._s.hasCompleted[i]) {
return;
}
}
this._s.finished = true;
var res = tryCatch(this._cb).apply(null, this._s.results);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onNext(res);
this._o.onCompleted();
}
};
function ForkJoinObservable(sources, cb) {
this._sources = sources;
this._cb = cb;
ObservableBase.call(this);
}
inherits(ForkJoinObservable, ObservableBase);
ForkJoinObservable.prototype.subscribeCore = function (o) {
if (this._sources.length === 0) {
o.onCompleted();
return Disposable.empty;
}
var count = this._sources.length;
var state = {
finished: false,
hasResults: new Array(count),
hasCompleted: new Array(count),
results: new Array(count)
};
var subscriptions = new CompositeDisposable();
for (var i = 0, len = this._sources.length; i < len; i++) {
var source = this._sources[i];
isPromise(source) && (source = fromPromise(source));
subscriptions.add(source.subscribe(new ForkJoinObserver(o, state, i, this._cb, subscriptions)));
}
return subscriptions;
};
module.exports = function forkJoin() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
return new ForkJoinObservable(args, resultSelector);
};
/***/ },
/* 50 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var ObservableBase = __webpack_require__(11);
var Scheduler = __webpack_require__(12);
var isFunction = __webpack_require__(9);
var $iterator$ = __webpack_require__(51);
var bindCallback = __webpack_require__(52);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var doneEnumerator = { done: true, value: undefined };
var maxSafeInteger = Math.pow(2, 53) - 1;
function numberIsFinite(value) {
return typeof value === 'number' && global.isFinite(value);
}
function sign(value) {
var number = +value;
if (number === 0) {
return number;
}
if (isNaN(number)) {
return number;
}
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) {
return 0;
}
if (len === 0 || !numberIsFinite(len)) {
return len;
}
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) {
return 0;
}
if (len > maxSafeInteger) {
return maxSafeInteger;
}
return len;
}
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function getIterable(o) {
var i = o[$iterator$],
it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) {
throw new TypeError('Object is not iterable');
}
return o[$iterator$]();
}
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(FromObservable, ObservableBase);
function scheduleRecursive(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) {
return o.onError(next.e);
}
if (next.done) {
return o.onCompleted();
}
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) {
return o.onError(result.e);
}
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, scheduleRecursive(o, it, this._fn));
};
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
module.exports = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.');
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
var mapper;
if (mapFn) {
mapper = bindCallback(mapFn, thisArg, 2);
}
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new FromObservable(iterable, mapper, scheduler);
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 51 */
/***/ function(module, exports) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
// Shim in iterator support
var $iterator$ = typeof global.Symbol === 'function' && global.Symbol.iterator || '_es6shim_iterator_';
// Bug for mozilla version
if (global.Set && typeof new global.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
module.exports = $iterator$;
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 52 */
/***/ function(module, exports) {
'use strict';
module.exports = function bindCallback(func, thisArg, argCount) {
if (typeof thisArg === 'undefined') {
return func;
}
switch (argCount) {
case 0:
return function () {
return func.call(thisArg);
};
case 1:
return function (arg) {
return func.call(thisArg, arg);
};
case 2:
return function (value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function (value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function () {
return func.apply(thisArg, arguments);
};
};
/***/ },
/* 53 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var Scheduler = __webpack_require__(12);
var inherits = __webpack_require__(6);
function scheduleRecursive(state, recurse) {
if (state.i < state.len) {
state.o.onNext(state.args[state.i++]);
recurse(state);
} else {
state.o.onCompleted();
}
}
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(FromArrayObservable, ObservableBase);
FromArrayObservable.prototype.subscribeCore = function (o) {
var state = {
i: 0,
args: this._args,
len: this._args.length,
o: o
};
return this._scheduler.scheduleRecursive(state, scheduleRecursive);
};
module.exports = function fromArray(array, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new FromArrayObservable(array, scheduler);
};
/***/ },
/* 54 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var ObservableBase = __webpack_require__(11);
var fromEventPattern = __webpack_require__(55);
var publish = __webpack_require__(56);
var CompositeDisposable = __webpack_require__(14);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function isNodeList(el) {
if (global.StaticNodeList) {
// IE8 Specific
// instanceof is slower than Object#toString, but Object#toString will not work as intended in IE8
return el instanceof global.StaticNodeList || el instanceof global.NodeList;
} else {
return Object.prototype.toString.call(el) === '[object NodeList]';
}
}
function ListenDisposable(e, n, fn) {
this._e = e;
this._n = n;
this._fn = fn;
this._e.addEventListener(this._n, this._fn, false);
this.isDisposed = false;
}
ListenDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this._e.removeEventListener(this._n, this._fn, false);
this.isDisposed = true;
}
};
function createEventListener(el, eventName, handler) {
var disposables = new CompositeDisposable();
// Asume NodeList or HTMLCollection
var elemToString = Object.prototype.toString.call(el);
if (isNodeList(el) || elemToString === '[object HTMLCollection]') {
for (var i = 0, len = el.length; i < len; i++) {
disposables.add(createEventListener(el.item(i), eventName, handler));
}
} else if (el) {
disposables.add(new ListenDisposable(el, eventName, handler));
}
return disposables;
}
/**
* Configuration option to determine whether to use native events only
*/
global.Rx || (global.Rx = {});
global.Rx.config || (global.Rx.config = {});
global.Rx.config.useNativeEvents = false;
function EventObservable(el, name, fn) {
this._el = el;
this._n = name;
this._fn = fn;
ObservableBase.call(this);
}
inherits(EventObservable, ObservableBase);
function createHandler(o, fn) {
return function handler() {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) {
return o.onError(results.e);
}
}
o.onNext(results);
};
}
EventObservable.prototype.subscribeCore = function (o) {
return createEventListener(this._el, this._n, createHandler(o, this._fn));
};
/**
* Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList.
* @param {Object} element The DOMElement or NodeList to attach a listener.
* @param {String} eventName The event name to attach the observable sequence.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence of events from the specified element and the specified event.
*/
module.exports = function fromEvent(element, eventName, selector) {
// Node.js specific
if (element.addListener) {
return fromEventPattern(function (h) {
element.addListener(eventName, h);
}, function (h) {
element.removeListener(eventName, h);
}, selector);
}
// Use only if non-native events are allowed
if (!global.Rx.config.useNativeEvents) {
// Handles jq, Angular.js, Zepto, Marionette, Ember.js
if (typeof element.on === 'function' && typeof element.off === 'function') {
return fromEventPattern(function (h) {
element.on(eventName, h);
}, function (h) {
element.off(eventName, h);
}, selector);
}
}
return publish(new EventObservable(element, eventName, selector)).refCount();
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var publish = __webpack_require__(56);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function EventPatternDisposable(del, fn, ret) {
this._del = del;
this._fn = fn;
this._ret = ret;
this.isDisposed = false;
}
EventPatternDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
isFunction(this._del) && this._del(this._fn, this._ret);
this.isDisposed = true;
}
};
function EventPatternObservable(add, del, fn) {
this._add = add;
this._del = del;
this._fn = fn;
ObservableBase.call(this);
}
inherits(EventPatternObservable, ObservableBase);
function createHandler(o, fn) {
return function handler() {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) {
return o.onError(results.e);
}
}
o.onNext(results);
};
}
EventPatternObservable.prototype.subscribeCore = function (o) {
var fn = createHandler(o, this._fn);
var returnValue = this._add(fn);
return new EventPatternDisposable(this._del, fn, returnValue);
};
/**
* Creates an observable sequence from an event emitter via an addHandler/removeHandler pair.
* @param {Function} addHandler The function to add a handler to the emitter.
* @param {Function} [removeHandler] The optional function to remove a handler from an emitter.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence which wraps an event from an event emitter
*/
module.exports = function fromEventPattern(addHandler, removeHandler, selector) {
return publish(new EventPatternObservable(addHandler, removeHandler, selector)).refCount();
};
/***/ },
/* 56 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Subject = __webpack_require__(57);
var multicast = __webpack_require__(58);
var isFunction = __webpack_require__(9);
/**
* Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence.
* This operator is a specialization of Multicast using a regular Subject.
* @param {Function} [selector] Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all notifications of the source from the time of the subscription on.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
module.exports = function publish(source, fn) {
return fn && isFunction(fn) ? multicast(source, function () {
return new Subject();
}, fn) : multicast(source, new Subject());
};
/***/ },
/* 57 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(13);
var Observable = __webpack_require__(8);
var Observer = __webpack_require__(1);
var InnerSubscription = __webpack_require__(32);
var addProperties = __webpack_require__(33);
var cloneArray = __webpack_require__(34);
var inherits = __webpack_require__(6);
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
function Subject() {
Observable.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
inherits(Subject, Observable);
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return Disposable.empty;
}
o.onCompleted();
return Disposable.empty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () {
Disposable.checkDisposed(this);
return this.observers.length > 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
Subject.addToObject = function (operators) {
Object.keys(operators).forEach(function (operator) {
Subject[operator] = operators[operator];
});
};
Subject.addToPrototype = function (operators) {
Object.keys(operators).forEach(function (operator) {
Subject.prototype[operator] = function () {
var args = [this];
args.push.apply(args, arguments);
return operators[operator].apply(null, args);
};
});
};
module.exports = Subject;
/***/ },
/* 58 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var ConnectableObservable = __webpack_require__(59);
var BinaryDisposable = __webpack_require__(24);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
function MulticastObservable(source, fn1, fn2) {
this.source = source;
this._fn1 = fn1;
this._fn2 = fn2;
ObservableBase.call(this);
}
inherits(MulticastObservable, ObservableBase);
MulticastObservable.prototype.subscribeCore = function (o) {
var connectable = this.source.multicast(this._fn1());
return new BinaryDisposable(this._fn2(connectable).subscribe(o), connectable.connect());
};
/**
* Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
* subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
* invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
* @param {Function|Subject} subjectOrSubjectSelector
* Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
* Or:
* Subject to push source elements into.
*
* @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if 0) {
state.n--;
}
state.o.onNext(state.value);
recurse(state);
}
RepeatValueObservable.prototype.subscribeCore = function (o) {
var state = {
value: this._value,
n: this._count,
o: o
};
return this._scheduler.scheduleRecursive(state, scheduleRecursive);
};
module.exports = function repeatValue(value, repeatCount, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new RepeatValueObservable(value, repeatCount, scheduler);
};
/***/ },
/* 73 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var ObservableBase = __webpack_require__(11);
var fromArray = __webpack_require__(50);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var AbstractObserver = __webpack_require__(5);
var BinaryDisposable = __webpack_require__(24);
var isEqual = __webpack_require__(74);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
var $iterator$ = typeof global.Symbol === 'function' && global.Symbol.iterator || '_es6shim_iterator_';
// Bug for mozilla version
if (global.Set && typeof new global.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
function isIterable(o) {
return o && o[$iterator$] !== undefined;
}
function isArrayLike(o) {
return o && o.length !== undefined;
}
function FirstObserver(state) {
this._s = state;
AbstractObserver.call(this);
}
inherits(FirstObserver, AbstractObserver);
FirstObserver.prototype.next = function (x) {
if (this._s.qr.length > 0) {
var v = this._s.qr.shift();
var equal = tryCatch(this._s.cmp)(v, x);
if (equal === errorObj) {
return this._s.o.onError(equal.e);
}
if (!equal) {
this._s.o.onNext(false);
this._s.o.onCompleted();
}
} else if (this._s.doner) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else {
this._s.ql.push(x);
}
};
FirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
FirstObserver.prototype.completed = function () {
this._s.donel = true;
if (this._s.ql.length === 0) {
if (this._s.qr.length > 0) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else if (this._s.doner) {
this._s.o.onNext(true);
this._s.o.onCompleted();
}
}
};
function SecondObserver(state) {
this._s = state;
AbstractObserver.call(this);
}
inherits(SecondObserver, AbstractObserver);
SecondObserver.prototype.next = function (x) {
if (this._s.ql.length > 0) {
var v = this._s.ql.shift();
var equal = tryCatch(this._s.cmp)(v, x);
if (equal === errorObj) {
return this._s.o.onError(equal.e);
}
if (!equal) {
this._s.o.onNext(false);
this._s.o.onCompleted();
}
} else if (this._s.donel) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else {
this._s.qr.push(x);
}
};
SecondObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SecondObserver.prototype.completed = function () {
this._s.doner = true;
if (this._s.qr.length === 0) {
if (this._s.ql.length > 0) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else if (this._s.donel) {
this._s.o.onNext(true);
this._s.o.onCompleted();
}
}
};
function SequenceEqualObservable(first, second, comparer) {
this._first = first;
this._second = second;
this._cmp = comparer;
ObservableBase.call(this);
}
inherits(SequenceEqualObservable, ObservableBase);
SequenceEqualObservable.prototype.subscribeCore = function (o) {
(isArrayLike(this._first) || isIterable(this._first)) && (this._first = fromArray(this._first));
isPromise(this._first) && (this._first = fromPromise(this._first));
(isArrayLike(this._second) || isIterable(this._second)) && (this._second = fromArray(this._second));
isPromise(this._second) && (this._second = fromPromise(this._second));
var state = {
o: o,
donel: false,
doner: false,
ql: [],
qr: [],
cmp: this._cmp
};
return new BinaryDisposable(this._first.subscribe(new FirstObserver(state)), this._second.subscribe(new SecondObserver(state)));
};
module.exports = function sequenceEqual(first, second, comparer) {
comparer || (comparer = isEqual);
return new SequenceEqualObservable(first, second, comparer);
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 74 */
/***/ function(module, exports) {
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString'),
dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [],
prop,
i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}();
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength,
key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor && 'constructor' in object && 'constructor' in other && !(typeof objCtor === 'function' && objCtor instanceof objCtor && typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return object !== +object ? other !== +other : object === +other;
case regexpTag:
case stringTag:
return object === other + '';
}
return false;
}
function isObject(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
}
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = function () {
try {
Object({ 'toString': 0 } + '');
} catch (e) {
return function () {
return false;
};
}
return function (value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}();
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function (value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome(array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function (othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
} else if (othTag !== objectTag) {
othIsArr = isTypedArray(other);
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || !isObject(value) && !isObjectLike(other)) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
module.exports = function (value, other) {
return baseIsEqual(value, other);
};
/***/ },
/* 75 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var toAsync = __webpack_require__(76);
module.exports = function start(func, context, scheduler) {
return toAsync(func, context, scheduler)();
};
/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AsyncSubject = __webpack_require__(31);
var asObservable = __webpack_require__(35);
var Scheduler = __webpack_require__(12);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function scheduleMethod(s, state) {
var result = tryCatch(state.func).apply(state.context, state.args);
if (result === errorObj) {
return state.subject.onError(result.e);
}
state.subject.onNext(result);
state.subject.onCompleted();
}
module.exports = function toAsync(func, context, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return function asyncFn() {
var subject = new AsyncSubject(),
len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var state = {
subject: subject,
args: args,
func: func,
context: context
};
scheduler.schedule(state, scheduleMethod);
return asObservable(subject);
};
};
/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var fromPromise = __webpack_require__(27);
var throwError = __webpack_require__(40);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
module.exports = function startAsync(functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) {
return throwError(promise.e);
}
return fromPromise(promise);
};
/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var defer = __webpack_require__(39);
var interval = __webpack_require__(63);
var Scheduler = __webpack_require__(12);
var inherits = __webpack_require__(6);
function TimerObservable(dt, s) {
this._dt = dt;
this._s = s;
ObservableBase.call(this);
}
inherits(TimerObservable, ObservableBase);
function scheduleTimer(s, o) {
o.onNext(0);
o.onCompleted();
}
TimerObservable.prototype.subscribeCore = function (o) {
return this._s.scheduleFuture(o, this._dt, scheduleTimer);
};
function TimerPeriodObservable(dt, period, scheduler) {
this._dt = dt;
this._period = Scheduler.normalize(period);
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(TimerPeriodObservable, ObservableBase);
function scheduleTimerPeriod(state, recurse) {
if (state.p > 0) {
var now = state.scheduler.now();
state.dt = new Date(state.dt.getTime() + state.p);
state.dt.getTime() <= now && (state.dt = new Date(now + state.p));
}
state.o.onNext(state.i++);
recurse(state, new Date(state.dt));
}
TimerPeriodObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
i: 0,
p: this._period,
dt: this._dt,
scheduler: this._scheduler
};
return this._scheduler.scheduleRecursiveFuture(state, this._dt, scheduleTimerPeriod);
};
function timerRelativeAndPeriod(dt, period, scheduler) {
if (dt === period) {
return interval(dt, scheduler);
}
return defer(function () {
return new TimerPeriodObservable(new Date(scheduler.now() + dt), period, scheduler);
});
}
/**
* Returns an observable sequence that produces a value after dueTime has elapsed and then after each period.
* @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value.
* @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring.
* @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used.
* @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period.
*/
module.exports = function timer(dueTime, periodOrScheduler, scheduler) {
var period;
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
if (periodOrScheduler != null && typeof periodOrScheduler === 'number') {
period = periodOrScheduler;
} else if (Scheduler.isScheduler(periodOrScheduler)) {
scheduler = periodOrScheduler;
}
if ((dueTime instanceof Date || typeof dueTime === 'number') && period === undefined) {
return new TimerObservable(dueTime, scheduler);
}
if (dueTime instanceof Date && period !== undefined) {
return new TimerPeriodObservable(dueTime, periodOrScheduler, scheduler);
}
return timerRelativeAndPeriod(dueTime, period, scheduler);
};
/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var throwError = __webpack_require__(40);
var CompositeDisposable = __webpack_require__(14);
var inherits = __webpack_require__(6);
__webpack_require__(80);
function WhenObserver(map, o) {
this._map = map;
this._o = o;
AbstractObserver.call(this);
}
inherits(WhenObserver, AbstractObserver);
WhenObserver.prototype.next = function (x) {
this._o.onNext(x);
};
WhenObserver.prototype.completed = function () {
this._o.onCompleted();
};
WhenObserver.prototype.error = function (e) {
this._map.forEach(function (v) {
v.onError(e);
});
this._o.onError(e);
};
function WhenObservable(plans) {
this._plans = plans;
ObservableBase.call(this);
}
inherits(WhenObservable, ObservableBase);
WhenObservable.prototype.subscribeCore = function (o) {
var activePlans = [],
externalSubscriptions = new global.Map(),
outObserver = new WhenObserver(externalSubscriptions, o);
try {
for (var i = 0, len = this._plans.length; i < len; i++) {
activePlans.push(this._plans[i].activate(externalSubscriptions, outObserver, function (activePlan) {
var idx = activePlans.indexOf(activePlan);
activePlans.splice(idx, 1);
activePlans.length === 0 && o.onCompleted();
}));
}
} catch (e) {
return throwError(e).subscribe(o);
}
var group = new CompositeDisposable();
externalSubscriptions.forEach(function (joinObserver) {
joinObserver.subscribe();
group.add(joinObserver);
});
return group;
};
/**
* Joins together the results from several patterns.
*
* @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns.
* @returns {Observable} Observable sequence with the results form matching several patterns.
*/
module.exports = function when() {
var len = arguments.length,
plans = new Array(len);
for (var i = 0; i < len; i++) {
plans[i] = arguments[i];
}
return new WhenObservable(plans);
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
if (!__webpack_require__(81)()) {
Object.defineProperty(__webpack_require__(82), 'Map',
{ value: __webpack_require__(83), configurable: true, enumerable: false,
writable: true });
}
/***/ },
/* 81 */
/***/ function(module, exports) {
'use strict';
module.exports = function () {
var map, iterator, result;
if (typeof Map !== 'function') return false;
try {
// WebKit doesn't support arguments and crashes
map = new Map([['raz', 'one'], ['dwa', 'two'], ['trzy', 'three']]);
} catch (e) {
return false;
}
if (String(map) !== '[object Map]') return false;
if (map.size !== 3) return false;
if (typeof map.clear !== 'function') return false;
if (typeof map.delete !== 'function') return false;
if (typeof map.entries !== 'function') return false;
if (typeof map.forEach !== 'function') return false;
if (typeof map.get !== 'function') return false;
if (typeof map.has !== 'function') return false;
if (typeof map.keys !== 'function') return false;
if (typeof map.set !== 'function') return false;
if (typeof map.values !== 'function') return false;
iterator = map.entries();
result = iterator.next();
if (result.done !== false) return false;
if (!result.value) return false;
if (result.value[0] !== 'raz') return false;
if (result.value[1] !== 'one') return false;
return true;
};
/***/ },
/* 82 */
/***/ function(module, exports) {
'use strict';
module.exports = new Function("return this")();
/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var clear = __webpack_require__(84)
, eIndexOf = __webpack_require__(86)
, setPrototypeOf = __webpack_require__(92)
, callable = __webpack_require__(97)
, validValue = __webpack_require__(85)
, d = __webpack_require__(98)
, ee = __webpack_require__(110)
, Symbol = __webpack_require__(111)
, iterator = __webpack_require__(116)
, forOf = __webpack_require__(120)
, Iterator = __webpack_require__(130)
, isNative = __webpack_require__(133)
, call = Function.prototype.call
, defineProperties = Object.defineProperties, getPrototypeOf = Object.getPrototypeOf
, MapPoly;
module.exports = MapPoly = function (/*iterable*/) {
var iterable = arguments[0], keys, values, self;
if (!(this instanceof MapPoly)) throw new TypeError('Constructor requires \'new\'');
if (isNative && setPrototypeOf && (Map !== MapPoly)) {
self = setPrototypeOf(new Map(), getPrototypeOf(this));
} else {
self = this;
}
if (iterable != null) iterator(iterable);
defineProperties(self, {
__mapKeysData__: d('c', keys = []),
__mapValuesData__: d('c', values = [])
});
if (!iterable) return self;
forOf(iterable, function (value) {
var key = validValue(value)[0];
value = value[1];
if (eIndexOf.call(keys, key) !== -1) return;
keys.push(key);
values.push(value);
}, self);
return self;
};
if (isNative) {
if (setPrototypeOf) setPrototypeOf(MapPoly, Map);
MapPoly.prototype = Object.create(Map.prototype, {
constructor: d(MapPoly)
});
}
ee(defineProperties(MapPoly.prototype, {
clear: d(function () {
if (!this.__mapKeysData__.length) return;
clear.call(this.__mapKeysData__);
clear.call(this.__mapValuesData__);
this.emit('_clear');
}),
delete: d(function (key) {
var index = eIndexOf.call(this.__mapKeysData__, key);
if (index === -1) return false;
this.__mapKeysData__.splice(index, 1);
this.__mapValuesData__.splice(index, 1);
this.emit('_delete', index, key);
return true;
}),
entries: d(function () { return new Iterator(this, 'key+value'); }),
forEach: d(function (cb/*, thisArg*/) {
var thisArg = arguments[1], iterator, result;
callable(cb);
iterator = this.entries();
result = iterator._next();
while (result !== undefined) {
call.call(cb, thisArg, this.__mapValuesData__[result],
this.__mapKeysData__[result], this);
result = iterator._next();
}
}),
get: d(function (key) {
var index = eIndexOf.call(this.__mapKeysData__, key);
if (index === -1) return;
return this.__mapValuesData__[index];
}),
has: d(function (key) {
return (eIndexOf.call(this.__mapKeysData__, key) !== -1);
}),
keys: d(function () { return new Iterator(this, 'key'); }),
set: d(function (key, value) {
var index = eIndexOf.call(this.__mapKeysData__, key), emit;
if (index === -1) {
index = this.__mapKeysData__.push(key) - 1;
emit = true;
}
this.__mapValuesData__[index] = value;
if (emit) this.emit('_add', index, key);
return this;
}),
size: d.gs(function () { return this.__mapKeysData__.length; }),
values: d(function () { return new Iterator(this, 'value'); }),
toString: d(function () { return '[object Map]'; })
}));
Object.defineProperty(MapPoly.prototype, Symbol.iterator, d(function () {
return this.entries();
}));
Object.defineProperty(MapPoly.prototype, Symbol.toStringTag, d('c', 'Map'));
/***/ },
/* 84 */
/***/ function(module, exports, __webpack_require__) {
// Inspired by Google Closure:
// http://closure-library.googlecode.com/svn/docs/
// closure_goog_array_array.js.html#goog.array.clear
'use strict';
var value = __webpack_require__(85);
module.exports = function () {
value(this).length = 0;
return this;
};
/***/ },
/* 85 */
/***/ function(module, exports) {
'use strict';
module.exports = function (value) {
if (value == null) throw new TypeError("Cannot use null or undefined");
return value;
};
/***/ },
/* 86 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var toPosInt = __webpack_require__(87)
, value = __webpack_require__(85)
, indexOf = Array.prototype.indexOf
, hasOwnProperty = Object.prototype.hasOwnProperty
, abs = Math.abs, floor = Math.floor;
module.exports = function (searchElement/*, fromIndex*/) {
var i, l, fromIndex, val;
if (searchElement === searchElement) { //jslint: ignore
return indexOf.apply(this, arguments);
}
l = toPosInt(value(this).length);
fromIndex = arguments[1];
if (isNaN(fromIndex)) fromIndex = 0;
else if (fromIndex >= 0) fromIndex = floor(fromIndex);
else fromIndex = toPosInt(this.length) - floor(abs(fromIndex));
for (i = fromIndex; i < l; ++i) {
if (hasOwnProperty.call(this, i)) {
val = this[i];
if (val !== val) return i; //jslint: ignore
}
}
return -1;
};
/***/ },
/* 87 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var toInteger = __webpack_require__(88)
, max = Math.max;
module.exports = function (value) { return max(0, toInteger(value)); };
/***/ },
/* 88 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var sign = __webpack_require__(89)
, abs = Math.abs, floor = Math.floor;
module.exports = function (value) {
if (isNaN(value)) return 0;
value = Number(value);
if ((value === 0) || !isFinite(value)) return value;
return sign(value) * floor(abs(value));
};
/***/ },
/* 89 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(90)()
? Math.sign
: __webpack_require__(91);
/***/ },
/* 90 */
/***/ function(module, exports) {
'use strict';
module.exports = function () {
var sign = Math.sign;
if (typeof sign !== 'function') return false;
return ((sign(10) === 1) && (sign(-20) === -1));
};
/***/ },
/* 91 */
/***/ function(module, exports) {
'use strict';
module.exports = function (value) {
value = Number(value);
if (isNaN(value) || (value === 0)) return value;
return (value > 0) ? 1 : -1;
};
/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(93)()
? Object.setPrototypeOf
: __webpack_require__(94);
/***/ },
/* 93 */
/***/ function(module, exports) {
'use strict';
var create = Object.create, getPrototypeOf = Object.getPrototypeOf
, x = {};
module.exports = function (/*customCreate*/) {
var setPrototypeOf = Object.setPrototypeOf
, customCreate = arguments[0] || create;
if (typeof setPrototypeOf !== 'function') return false;
return getPrototypeOf(setPrototypeOf(customCreate(null), x)) === x;
};
/***/ },
/* 94 */
/***/ function(module, exports, __webpack_require__) {
// Big thanks to @WebReflection for sorting this out
// https://gist.github.com/WebReflection/5593554
'use strict';
var isObject = __webpack_require__(95)
, value = __webpack_require__(85)
, isPrototypeOf = Object.prototype.isPrototypeOf
, defineProperty = Object.defineProperty
, nullDesc = { configurable: true, enumerable: false, writable: true,
value: undefined }
, validate;
validate = function (obj, prototype) {
value(obj);
if ((prototype === null) || isObject(prototype)) return obj;
throw new TypeError('Prototype must be null or an object');
};
module.exports = (function (status) {
var fn, set;
if (!status) return null;
if (status.level === 2) {
if (status.set) {
set = status.set;
fn = function (obj, prototype) {
set.call(validate(obj, prototype), prototype);
return obj;
};
} else {
fn = function (obj, prototype) {
validate(obj, prototype).__proto__ = prototype;
return obj;
};
}
} else {
fn = function self(obj, prototype) {
var isNullBase;
validate(obj, prototype);
isNullBase = isPrototypeOf.call(self.nullPolyfill, obj);
if (isNullBase) delete self.nullPolyfill.__proto__;
if (prototype === null) prototype = self.nullPolyfill;
obj.__proto__ = prototype;
if (isNullBase) defineProperty(self.nullPolyfill, '__proto__', nullDesc);
return obj;
};
}
return Object.defineProperty(fn, 'level', { configurable: false,
enumerable: false, writable: false, value: status.level });
}((function () {
var x = Object.create(null), y = {}, set
, desc = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
if (desc) {
try {
set = desc.set; // Opera crashes at this point
set.call(x, y);
} catch (ignore) { }
if (Object.getPrototypeOf(x) === y) return { set: set, level: 2 };
}
x.__proto__ = y;
if (Object.getPrototypeOf(x) === y) return { level: 2 };
x = {};
x.__proto__ = y;
if (Object.getPrototypeOf(x) === y) return { level: 1 };
return false;
}())));
__webpack_require__(96);
/***/ },
/* 95 */
/***/ function(module, exports) {
'use strict';
var map = { function: true, object: true };
module.exports = function (x) {
return ((x != null) && map[typeof x]) || false;
};
/***/ },
/* 96 */
/***/ function(module, exports, __webpack_require__) {
// Workaround for http://code.google.com/p/v8/issues/detail?id=2804
'use strict';
var create = Object.create, shim;
if (!__webpack_require__(93)()) {
shim = __webpack_require__(94);
}
module.exports = (function () {
var nullObject, props, desc;
if (!shim) return create;
if (shim.level !== 1) return create;
nullObject = {};
props = {};
desc = { configurable: false, enumerable: false, writable: true,
value: undefined };
Object.getOwnPropertyNames(Object.prototype).forEach(function (name) {
if (name === '__proto__') {
props[name] = { configurable: true, enumerable: false, writable: true,
value: undefined };
return;
}
props[name] = desc;
});
Object.defineProperties(nullObject, props);
Object.defineProperty(shim, 'nullPolyfill', { configurable: false,
enumerable: false, writable: false, value: nullObject });
return function (prototype, props) {
return create((prototype === null) ? nullObject : prototype, props);
};
}());
/***/ },
/* 97 */
/***/ function(module, exports) {
'use strict';
module.exports = function (fn) {
if (typeof fn !== 'function') throw new TypeError(fn + " is not a function");
return fn;
};
/***/ },
/* 98 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var assign = __webpack_require__(99)
, normalizeOpts = __webpack_require__(105)
, isCallable = __webpack_require__(106)
, contains = __webpack_require__(107)
, d;
d = module.exports = function (dscr, value/*, options*/) {
var c, e, w, options, desc;
if ((arguments.length < 2) || (typeof dscr !== 'string')) {
options = value;
value = dscr;
dscr = null;
} else {
options = arguments[2];
}
if (dscr == null) {
c = w = true;
e = false;
} else {
c = contains.call(dscr, 'c');
e = contains.call(dscr, 'e');
w = contains.call(dscr, 'w');
}
desc = { value: value, configurable: c, enumerable: e, writable: w };
return !options ? desc : assign(normalizeOpts(options), desc);
};
d.gs = function (dscr, get, set/*, options*/) {
var c, e, options, desc;
if (typeof dscr !== 'string') {
options = set;
set = get;
get = dscr;
dscr = null;
} else {
options = arguments[3];
}
if (get == null) {
get = undefined;
} else if (!isCallable(get)) {
options = get;
get = set = undefined;
} else if (set == null) {
set = undefined;
} else if (!isCallable(set)) {
options = set;
set = undefined;
}
if (dscr == null) {
c = true;
e = false;
} else {
c = contains.call(dscr, 'c');
e = contains.call(dscr, 'e');
}
desc = { get: get, set: set, configurable: c, enumerable: e };
return !options ? desc : assign(normalizeOpts(options), desc);
};
/***/ },
/* 99 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(100)()
? Object.assign
: __webpack_require__(101);
/***/ },
/* 100 */
/***/ function(module, exports) {
'use strict';
module.exports = function () {
var assign = Object.assign, obj;
if (typeof assign !== 'function') return false;
obj = { foo: 'raz' };
assign(obj, { bar: 'dwa' }, { trzy: 'trzy' });
return (obj.foo + obj.bar + obj.trzy) === 'razdwatrzy';
};
/***/ },
/* 101 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var keys = __webpack_require__(102)
, value = __webpack_require__(85)
, max = Math.max;
module.exports = function (dest, src/*, …srcn*/) {
var error, i, l = max(arguments.length, 2), assign;
dest = Object(value(dest));
assign = function (key) {
try { dest[key] = src[key]; } catch (e) {
if (!error) error = e;
}
};
for (i = 1; i < l; ++i) {
src = arguments[i];
keys(src).forEach(assign);
}
if (error !== undefined) throw error;
return dest;
};
/***/ },
/* 102 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(103)()
? Object.keys
: __webpack_require__(104);
/***/ },
/* 103 */
/***/ function(module, exports) {
'use strict';
module.exports = function () {
try {
Object.keys('primitive');
return true;
} catch (e) { return false; }
};
/***/ },
/* 104 */
/***/ function(module, exports) {
'use strict';
var keys = Object.keys;
module.exports = function (object) {
return keys(object == null ? object : Object(object));
};
/***/ },
/* 105 */
/***/ function(module, exports) {
'use strict';
var forEach = Array.prototype.forEach, create = Object.create;
var process = function (src, obj) {
var key;
for (key in src) obj[key] = src[key];
};
module.exports = function (options/*, …options*/) {
var result = create(null);
forEach.call(arguments, function (options) {
if (options == null) return;
process(Object(options), result);
});
return result;
};
/***/ },
/* 106 */
/***/ function(module, exports) {
// Deprecated
'use strict';
module.exports = function (obj) { return typeof obj === 'function'; };
/***/ },
/* 107 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(108)()
? String.prototype.contains
: __webpack_require__(109);
/***/ },
/* 108 */
/***/ function(module, exports) {
'use strict';
var str = 'razdwatrzy';
module.exports = function () {
if (typeof str.contains !== 'function') return false;
return ((str.contains('dwa') === true) && (str.contains('foo') === false));
};
/***/ },
/* 109 */
/***/ function(module, exports) {
'use strict';
var indexOf = String.prototype.indexOf;
module.exports = function (searchString/*, position*/) {
return indexOf.call(this, searchString, arguments[1]) > -1;
};
/***/ },
/* 110 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var d = __webpack_require__(98)
, callable = __webpack_require__(97)
, apply = Function.prototype.apply, call = Function.prototype.call
, create = Object.create, defineProperty = Object.defineProperty
, defineProperties = Object.defineProperties
, hasOwnProperty = Object.prototype.hasOwnProperty
, descriptor = { configurable: true, enumerable: false, writable: true }
, on, once, off, emit, methods, descriptors, base;
on = function (type, listener) {
var data;
callable(listener);
if (!hasOwnProperty.call(this, '__ee__')) {
data = descriptor.value = create(null);
defineProperty(this, '__ee__', descriptor);
descriptor.value = null;
} else {
data = this.__ee__;
}
if (!data[type]) data[type] = listener;
else if (typeof data[type] === 'object') data[type].push(listener);
else data[type] = [data[type], listener];
return this;
};
once = function (type, listener) {
var once, self;
callable(listener);
self = this;
on.call(this, type, once = function () {
off.call(self, type, once);
apply.call(listener, this, arguments);
});
once.__eeOnceListener__ = listener;
return this;
};
off = function (type, listener) {
var data, listeners, candidate, i;
callable(listener);
if (!hasOwnProperty.call(this, '__ee__')) return this;
data = this.__ee__;
if (!data[type]) return this;
listeners = data[type];
if (typeof listeners === 'object') {
for (i = 0; (candidate = listeners[i]); ++i) {
if ((candidate === listener) ||
(candidate.__eeOnceListener__ === listener)) {
if (listeners.length === 2) data[type] = listeners[i ? 0 : 1];
else listeners.splice(i, 1);
}
}
} else {
if ((listeners === listener) ||
(listeners.__eeOnceListener__ === listener)) {
delete data[type];
}
}
return this;
};
emit = function (type) {
var i, l, listener, listeners, args;
if (!hasOwnProperty.call(this, '__ee__')) return;
listeners = this.__ee__[type];
if (!listeners) return;
if (typeof listeners === 'object') {
l = arguments.length;
args = new Array(l - 1);
for (i = 1; i < l; ++i) args[i - 1] = arguments[i];
listeners = listeners.slice();
for (i = 0; (listener = listeners[i]); ++i) {
apply.call(listener, this, args);
}
} else {
switch (arguments.length) {
case 1:
call.call(listeners, this);
break;
case 2:
call.call(listeners, this, arguments[1]);
break;
case 3:
call.call(listeners, this, arguments[1], arguments[2]);
break;
default:
l = arguments.length;
args = new Array(l - 1);
for (i = 1; i < l; ++i) {
args[i - 1] = arguments[i];
}
apply.call(listeners, this, args);
}
}
};
methods = {
on: on,
once: once,
off: off,
emit: emit
};
descriptors = {
on: d(on),
once: d(once),
off: d(off),
emit: d(emit)
};
base = defineProperties({}, descriptors);
module.exports = exports = function (o) {
return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
};
exports.methods = methods;
/***/ },
/* 111 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(112)() ? Symbol : __webpack_require__(113);
/***/ },
/* 112 */
/***/ function(module, exports) {
'use strict';
module.exports = function () {
var symbol;
if (typeof Symbol !== 'function') return false;
symbol = Symbol('test symbol');
try { String(symbol); } catch (e) { return false; }
if (typeof Symbol.iterator === 'symbol') return true;
// Return 'true' for polyfills
if (typeof Symbol.isConcatSpreadable !== 'object') return false;
if (typeof Symbol.iterator !== 'object') return false;
if (typeof Symbol.toPrimitive !== 'object') return false;
if (typeof Symbol.toStringTag !== 'object') return false;
if (typeof Symbol.unscopables !== 'object') return false;
return true;
};
/***/ },
/* 113 */
/***/ function(module, exports, __webpack_require__) {
// ES2015 Symbol polyfill for environments that do not support it (or partially support it_
'use strict';
var d = __webpack_require__(98)
, validateSymbol = __webpack_require__(114)
, create = Object.create, defineProperties = Object.defineProperties
, defineProperty = Object.defineProperty, objPrototype = Object.prototype
, NativeSymbol, SymbolPolyfill, HiddenSymbol, globalSymbols = create(null);
if (typeof Symbol === 'function') NativeSymbol = Symbol;
var generateName = (function () {
var created = create(null);
return function (desc) {
var postfix = 0, name, ie11BugWorkaround;
while (created[desc + (postfix || '')]) ++postfix;
desc += (postfix || '');
created[desc] = true;
name = '@@' + desc;
defineProperty(objPrototype, name, d.gs(null, function (value) {
// For IE11 issue see:
// https://connect.microsoft.com/IE/feedbackdetail/view/1928508/
// ie11-broken-getters-on-dom-objects
// https://github.com/medikoo/es6-symbol/issues/12
if (ie11BugWorkaround) return;
ie11BugWorkaround = true;
defineProperty(this, name, d(value));
ie11BugWorkaround = false;
}));
return name;
};
}());
// Internal constructor (not one exposed) for creating Symbol instances.
// This one is used to ensure that `someSymbol instanceof Symbol` always return false
HiddenSymbol = function Symbol(description) {
if (this instanceof HiddenSymbol) throw new TypeError('TypeError: Symbol is not a constructor');
return SymbolPolyfill(description);
};
// Exposed `Symbol` constructor
// (returns instances of HiddenSymbol)
module.exports = SymbolPolyfill = function Symbol(description) {
var symbol;
if (this instanceof Symbol) throw new TypeError('TypeError: Symbol is not a constructor');
symbol = create(HiddenSymbol.prototype);
description = (description === undefined ? '' : String(description));
return defineProperties(symbol, {
__description__: d('', description),
__name__: d('', generateName(description))
});
};
defineProperties(SymbolPolyfill, {
for: d(function (key) {
if (globalSymbols[key]) return globalSymbols[key];
return (globalSymbols[key] = SymbolPolyfill(String(key)));
}),
keyFor: d(function (s) {
var key;
validateSymbol(s);
for (key in globalSymbols) if (globalSymbols[key] === s) return key;
}),
// If there's native implementation of given symbol, let's fallback to it
// to ensure proper interoperability with other native functions e.g. Array.from
hasInstance: d('', (NativeSymbol && NativeSymbol.hasInstance) || SymbolPolyfill('hasInstance')),
isConcatSpreadable: d('', (NativeSymbol && NativeSymbol.isConcatSpreadable) ||
SymbolPolyfill('isConcatSpreadable')),
iterator: d('', (NativeSymbol && NativeSymbol.iterator) || SymbolPolyfill('iterator')),
match: d('', (NativeSymbol && NativeSymbol.match) || SymbolPolyfill('match')),
replace: d('', (NativeSymbol && NativeSymbol.replace) || SymbolPolyfill('replace')),
search: d('', (NativeSymbol && NativeSymbol.search) || SymbolPolyfill('search')),
species: d('', (NativeSymbol && NativeSymbol.species) || SymbolPolyfill('species')),
split: d('', (NativeSymbol && NativeSymbol.split) || SymbolPolyfill('split')),
toPrimitive: d('', (NativeSymbol && NativeSymbol.toPrimitive) || SymbolPolyfill('toPrimitive')),
toStringTag: d('', (NativeSymbol && NativeSymbol.toStringTag) || SymbolPolyfill('toStringTag')),
unscopables: d('', (NativeSymbol && NativeSymbol.unscopables) || SymbolPolyfill('unscopables'))
});
// Internal tweaks for real symbol producer
defineProperties(HiddenSymbol.prototype, {
constructor: d(SymbolPolyfill),
toString: d('', function () { return this.__name__; })
});
// Proper implementation of methods exposed on Symbol.prototype
// They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype
defineProperties(SymbolPolyfill.prototype, {
toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
valueOf: d(function () { return validateSymbol(this); })
});
defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d('',
function () { return validateSymbol(this); }));
defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d('c', 'Symbol'));
// Proper implementaton of toPrimitive and toStringTag for returned symbol instances
defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag,
d('c', SymbolPolyfill.prototype[SymbolPolyfill.toStringTag]));
// Note: It's important to define `toPrimitive` as last one, as some implementations
// implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)
// And that may invoke error in definition flow:
// See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149
defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive,
d('c', SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive]));
/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isSymbol = __webpack_require__(115);
module.exports = function (value) {
if (!isSymbol(value)) throw new TypeError(value + " is not a symbol");
return value;
};
/***/ },
/* 115 */
/***/ function(module, exports) {
'use strict';
module.exports = function (x) {
return (x && ((typeof x === 'symbol') || (x['@@toStringTag'] === 'Symbol'))) || false;
};
/***/ },
/* 116 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isIterable = __webpack_require__(117);
module.exports = function (value) {
if (!isIterable(value)) throw new TypeError(value + " is not iterable");
return value;
};
/***/ },
/* 117 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isArguments = __webpack_require__(118)
, isString = __webpack_require__(119)
, iteratorSymbol = __webpack_require__(111).iterator
, isArray = Array.isArray;
module.exports = function (value) {
if (value == null) return false;
if (isArray(value)) return true;
if (isString(value)) return true;
if (isArguments(value)) return true;
return (typeof value[iteratorSymbol] === 'function');
};
/***/ },
/* 118 */
/***/ function(module, exports) {
'use strict';
var toString = Object.prototype.toString
, id = toString.call((function () { return arguments; }()));
module.exports = function (x) { return (toString.call(x) === id); };
/***/ },
/* 119 */
/***/ function(module, exports) {
'use strict';
var toString = Object.prototype.toString
, id = toString.call('');
module.exports = function (x) {
return (typeof x === 'string') || (x && (typeof x === 'object') &&
((x instanceof String) || (toString.call(x) === id))) || false;
};
/***/ },
/* 120 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isArguments = __webpack_require__(118)
, callable = __webpack_require__(97)
, isString = __webpack_require__(119)
, get = __webpack_require__(121)
, isArray = Array.isArray, call = Function.prototype.call
, some = Array.prototype.some;
module.exports = function (iterable, cb/*, thisArg*/) {
var mode, thisArg = arguments[2], result, doBreak, broken, i, l, char, code;
if (isArray(iterable) || isArguments(iterable)) mode = 'array';
else if (isString(iterable)) mode = 'string';
else iterable = get(iterable);
callable(cb);
doBreak = function () { broken = true; };
if (mode === 'array') {
some.call(iterable, function (value) {
call.call(cb, thisArg, value, doBreak);
if (broken) return true;
});
return;
}
if (mode === 'string') {
l = iterable.length;
for (i = 0; i < l; ++i) {
char = iterable[i];
if ((i + 1) < l) {
code = char.charCodeAt(0);
if ((code >= 0xD800) && (code <= 0xDBFF)) char += iterable[++i];
}
call.call(cb, thisArg, char, doBreak);
if (broken) break;
}
return;
}
result = iterable.next();
while (!result.done) {
call.call(cb, thisArg, result.value, doBreak);
if (broken) return;
result = iterable.next();
}
};
/***/ },
/* 121 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isArguments = __webpack_require__(118)
, isString = __webpack_require__(119)
, ArrayIterator = __webpack_require__(122)
, StringIterator = __webpack_require__(129)
, iterable = __webpack_require__(116)
, iteratorSymbol = __webpack_require__(111).iterator;
module.exports = function (obj) {
if (typeof iterable(obj)[iteratorSymbol] === 'function') return obj[iteratorSymbol]();
if (isArguments(obj)) return new ArrayIterator(obj);
if (isString(obj)) return new StringIterator(obj);
return new ArrayIterator(obj);
};
/***/ },
/* 122 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var setPrototypeOf = __webpack_require__(92)
, contains = __webpack_require__(107)
, d = __webpack_require__(98)
, Iterator = __webpack_require__(123)
, defineProperty = Object.defineProperty
, ArrayIterator;
ArrayIterator = module.exports = function (arr, kind) {
if (!(this instanceof ArrayIterator)) return new ArrayIterator(arr, kind);
Iterator.call(this, arr);
if (!kind) kind = 'value';
else if (contains.call(kind, 'key+value')) kind = 'key+value';
else if (contains.call(kind, 'key')) kind = 'key';
else kind = 'value';
defineProperty(this, '__kind__', d('', kind));
};
if (setPrototypeOf) setPrototypeOf(ArrayIterator, Iterator);
ArrayIterator.prototype = Object.create(Iterator.prototype, {
constructor: d(ArrayIterator),
_resolve: d(function (i) {
if (this.__kind__ === 'value') return this.__list__[i];
if (this.__kind__ === 'key+value') return [i, this.__list__[i]];
return i;
}),
toString: d(function () { return '[object Array Iterator]'; })
});
/***/ },
/* 123 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var clear = __webpack_require__(84)
, assign = __webpack_require__(99)
, callable = __webpack_require__(97)
, value = __webpack_require__(85)
, d = __webpack_require__(98)
, autoBind = __webpack_require__(124)
, Symbol = __webpack_require__(111)
, defineProperty = Object.defineProperty
, defineProperties = Object.defineProperties
, Iterator;
module.exports = Iterator = function (list, context) {
if (!(this instanceof Iterator)) return new Iterator(list, context);
defineProperties(this, {
__list__: d('w', value(list)),
__context__: d('w', context),
__nextIndex__: d('w', 0)
});
if (!context) return;
callable(context.on);
context.on('_add', this._onAdd);
context.on('_delete', this._onDelete);
context.on('_clear', this._onClear);
};
defineProperties(Iterator.prototype, assign({
constructor: d(Iterator),
_next: d(function () {
var i;
if (!this.__list__) return;
if (this.__redo__) {
i = this.__redo__.shift();
if (i !== undefined) return i;
}
if (this.__nextIndex__ < this.__list__.length) return this.__nextIndex__++;
this._unBind();
}),
next: d(function () { return this._createResult(this._next()); }),
_createResult: d(function (i) {
if (i === undefined) return { done: true, value: undefined };
return { done: false, value: this._resolve(i) };
}),
_resolve: d(function (i) { return this.__list__[i]; }),
_unBind: d(function () {
this.__list__ = null;
delete this.__redo__;
if (!this.__context__) return;
this.__context__.off('_add', this._onAdd);
this.__context__.off('_delete', this._onDelete);
this.__context__.off('_clear', this._onClear);
this.__context__ = null;
}),
toString: d(function () { return '[object Iterator]'; })
}, autoBind({
_onAdd: d(function (index) {
if (index >= this.__nextIndex__) return;
++this.__nextIndex__;
if (!this.__redo__) {
defineProperty(this, '__redo__', d('c', [index]));
return;
}
this.__redo__.forEach(function (redo, i) {
if (redo >= index) this.__redo__[i] = ++redo;
}, this);
this.__redo__.push(index);
}),
_onDelete: d(function (index) {
var i;
if (index >= this.__nextIndex__) return;
--this.__nextIndex__;
if (!this.__redo__) return;
i = this.__redo__.indexOf(index);
if (i !== -1) this.__redo__.splice(i, 1);
this.__redo__.forEach(function (redo, i) {
if (redo > index) this.__redo__[i] = --redo;
}, this);
}),
_onClear: d(function () {
if (this.__redo__) clear.call(this.__redo__);
this.__nextIndex__ = 0;
})
})));
defineProperty(Iterator.prototype, Symbol.iterator, d(function () {
return this;
}));
defineProperty(Iterator.prototype, Symbol.toStringTag, d('', 'Iterator'));
/***/ },
/* 124 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var copy = __webpack_require__(125)
, map = __webpack_require__(126)
, callable = __webpack_require__(97)
, validValue = __webpack_require__(85)
, bind = Function.prototype.bind, defineProperty = Object.defineProperty
, hasOwnProperty = Object.prototype.hasOwnProperty
, define;
define = function (name, desc, bindTo) {
var value = validValue(desc) && callable(desc.value), dgs;
dgs = copy(desc);
delete dgs.writable;
delete dgs.value;
dgs.get = function () {
if (hasOwnProperty.call(this, name)) return value;
desc.value = bind.call(value, (bindTo == null) ? this : this[bindTo]);
defineProperty(this, name, desc);
return this[name];
};
return dgs;
};
module.exports = function (props/*, bindTo*/) {
var bindTo = arguments[1];
return map(props, function (desc, name) {
return define(name, desc, bindTo);
});
};
/***/ },
/* 125 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var assign = __webpack_require__(99)
, value = __webpack_require__(85);
module.exports = function (obj) {
var copy = Object(value(obj));
if (copy !== obj) return copy;
return assign({}, obj);
};
/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var callable = __webpack_require__(97)
, forEach = __webpack_require__(127)
, call = Function.prototype.call;
module.exports = function (obj, cb/*, thisArg*/) {
var o = {}, thisArg = arguments[2];
callable(cb);
forEach(obj, function (value, key, obj, index) {
o[key] = call.call(cb, thisArg, value, key, obj, index);
});
return o;
};
/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(128)('forEach');
/***/ },
/* 128 */
/***/ function(module, exports, __webpack_require__) {
// Internal method, used by iteration functions.
// Calls a function for each key-value pair found in object
// Optionally takes compareFn to iterate object in specific order
'use strict';
var callable = __webpack_require__(97)
, value = __webpack_require__(85)
, bind = Function.prototype.bind, call = Function.prototype.call, keys = Object.keys
, propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
module.exports = function (method, defVal) {
return function (obj, cb/*, thisArg, compareFn*/) {
var list, thisArg = arguments[2], compareFn = arguments[3];
obj = Object(value(obj));
callable(cb);
list = keys(obj);
if (compareFn) {
list.sort((typeof compareFn === 'function') ? bind.call(compareFn, obj) : undefined);
}
if (typeof method !== 'function') method = list[method];
return call.call(method, list, function (key, index) {
if (!propertyIsEnumerable.call(obj, key)) return defVal;
return call.call(cb, thisArg, obj[key], key, obj, index);
});
};
};
/***/ },
/* 129 */
/***/ function(module, exports, __webpack_require__) {
// Thanks @mathiasbynens
// http://mathiasbynens.be/notes/javascript-unicode#iterating-over-symbols
'use strict';
var setPrototypeOf = __webpack_require__(92)
, d = __webpack_require__(98)
, Iterator = __webpack_require__(123)
, defineProperty = Object.defineProperty
, StringIterator;
StringIterator = module.exports = function (str) {
if (!(this instanceof StringIterator)) return new StringIterator(str);
str = String(str);
Iterator.call(this, str);
defineProperty(this, '__length__', d('', str.length));
};
if (setPrototypeOf) setPrototypeOf(StringIterator, Iterator);
StringIterator.prototype = Object.create(Iterator.prototype, {
constructor: d(StringIterator),
_next: d(function () {
if (!this.__list__) return;
if (this.__nextIndex__ < this.__length__) return this.__nextIndex__++;
this._unBind();
}),
_resolve: d(function (i) {
var char = this.__list__[i], code;
if (this.__nextIndex__ === this.__length__) return char;
code = char.charCodeAt(0);
if ((code >= 0xD800) && (code <= 0xDBFF)) return char + this.__list__[this.__nextIndex__++];
return char;
}),
toString: d(function () { return '[object String Iterator]'; })
});
/***/ },
/* 130 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var setPrototypeOf = __webpack_require__(92)
, d = __webpack_require__(98)
, Iterator = __webpack_require__(123)
, toStringTagSymbol = __webpack_require__(111).toStringTag
, kinds = __webpack_require__(131)
, defineProperties = Object.defineProperties
, unBind = Iterator.prototype._unBind
, MapIterator;
MapIterator = module.exports = function (map, kind) {
if (!(this instanceof MapIterator)) return new MapIterator(map, kind);
Iterator.call(this, map.__mapKeysData__, map);
if (!kind || !kinds[kind]) kind = 'key+value';
defineProperties(this, {
__kind__: d('', kind),
__values__: d('w', map.__mapValuesData__)
});
};
if (setPrototypeOf) setPrototypeOf(MapIterator, Iterator);
MapIterator.prototype = Object.create(Iterator.prototype, {
constructor: d(MapIterator),
_resolve: d(function (i) {
if (this.__kind__ === 'value') return this.__values__[i];
if (this.__kind__ === 'key') return this.__list__[i];
return [this.__list__[i], this.__values__[i]];
}),
_unBind: d(function () {
this.__values__ = null;
unBind.call(this);
}),
toString: d(function () { return '[object Map Iterator]'; })
});
Object.defineProperty(MapIterator.prototype, toStringTagSymbol,
d('c', 'Map Iterator'));
/***/ },
/* 131 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(132)('key',
'value', 'key+value');
/***/ },
/* 132 */
/***/ function(module, exports) {
'use strict';
var forEach = Array.prototype.forEach, create = Object.create;
module.exports = function (arg/*, …args*/) {
var set = create(null);
forEach.call(arguments, function (name) { set[name] = true; });
return set;
};
/***/ },
/* 133 */
/***/ function(module, exports) {
// Exports true if environment provides native `Map` implementation,
// whatever that is.
'use strict';
module.exports = (function () {
if (typeof Map === 'undefined') return false;
return (Object.prototype.toString.call(new Map()) === '[object Map]');
}());
/***/ },
/* 134 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var throwError = __webpack_require__(40);
var BinaryDisposable = __webpack_require__(24);
var Disposable = __webpack_require__(13);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function UsingObservable(resFn, obsFn) {
this._resFn = resFn;
this._obsFn = obsFn;
ObservableBase.call(this);
}
inherits(UsingObservable, ObservableBase);
UsingObservable.prototype.subscribeCore = function (o) {
var disposable = Disposable.empty;
var resource = tryCatch(this._resFn)();
if (resource === errorObj) {
return new BinaryDisposable(throwError(resource.e).subscribe(o), disposable);
}
resource && (disposable = resource);
var source = tryCatch(this._obsFn)(resource);
if (source === errorObj) {
return new BinaryDisposable(throwError(source.e).subscribe(o), disposable);
}
return new BinaryDisposable(source.subscribe(o), disposable);
};
/**
* Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime.
* @param {Function} resourceFactory Factory function to obtain a resource object.
* @param {Function} observableFactory Factory function to obtain an observable sequence that depends on the obtained resource.
* @returns {Observable} An observable sequence whose lifetime controls the lifetime of the dependent resource object.
*/
module.exports = function using(resourceFactory, observableFactory) {
return new UsingObservable(resourceFactory, observableFactory);
};
/***/ },
/* 135 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var SingleAssignmentDisposable = __webpack_require__(17);
var NAryDisposable = __webpack_require__(43);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var identity = __webpack_require__(46);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function falseFactory() {
return false;
}
function emptyArrayFactory() {
return [];
}
function initializeArray(n, fn) {
var results = new Array(n);
for (var i = 0; i < n; i++) {
results[i] = fn(i);
}
return results;
}
function argumentsToArray() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return args;
}
function ZipObserver(o, i, p, q, d) {
this._o = o;
this._i = i;
this._p = p;
this._q = q;
this._d = d;
AbstractObserver.call(this);
}
inherits(ZipObserver, AbstractObserver);
function notEmpty(x) {
return x.length > 0;
}
function shiftEach(x) {
return x.shift();
}
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
function ZipObservable(s, cb) {
this._s = s;
this._cb = cb;
ObservableBase.call(this);
}
inherits(ZipObservable, ObservableBase);
ZipObservable.prototype.subscribeCore = function (observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = initializeArray(n, falseFactory),
q = initializeArray(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i],
sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = fromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
module.exports = function zip() {
if (arguments.length === 0) {
throw new Error('invalid arguments');
}
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
return new ZipObservable(args, resultSelector);
};
/***/ },
/* 136 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Pattern = __webpack_require__(137);
module.exports = function and(left, right) {
return new Pattern([left, right]);
};
/***/ },
/* 137 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Plan = __webpack_require__(138);
/**
* @constructor
* Represents a join pattern over observable sequences.
*/
function Pattern(patterns) {
this._patterns = patterns;
}
/**
* Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value.
* @param other Observable sequence to match in addition to the current pattern.
* @return {Pattern} Pattern object that matches when all observable sequences in the pattern have an available value.
*/
Pattern.prototype.and = function (other) {
return new Pattern(this._patterns.concat(other));
};
/**
* Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values.
* @param {Function} selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern.
* @return {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator.
*/
Pattern.prototype.thenDo = function (selector) {
return new Plan(this, selector);
};
module.exports = Pattern;
/***/ },
/* 138 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ActivePlan = __webpack_require__(139);
var JoinObserver = __webpack_require__(140);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function planCreateObserver(externalSubscriptions, observable, onError) {
var entry = externalSubscriptions.get(observable);
if (!entry) {
var observer = new JoinObserver(observable, onError);
externalSubscriptions.set(observable, observer);
return observer;
}
return entry;
}
function Plan(expression, selector) {
this._expression = expression;
this._selector = selector;
}
function handleOnError(o) {
return function (e) {
o.onError(e);
};
}
function handleOnNext(self, observer) {
return function onNext() {
var result = tryCatch(self._selector).apply(self, arguments);
if (result === errorObj) {
return observer.onError(result.e);
}
observer.onNext(result);
};
}
Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) {
var joinObservers = [],
errHandler = handleOnError(observer);
for (var i = 0, len = this._expression._patterns.length; i < len; i++) {
joinObservers.push(planCreateObserver(externalSubscriptions, this._expression._patterns[i], errHandler));
}
var activePlan = new ActivePlan(joinObservers, handleOnNext(this, observer), function () {
for (var j = 0, jlen = joinObservers.length; j < jlen; j++) {
joinObservers[j].removeActivePlan(activePlan);
}
deactivate(activePlan);
});
for (i = 0, len = joinObservers.length; i < len; i++) {
joinObservers[i].addActivePlan(activePlan);
}
return activePlan;
};
module.exports = Plan;
/***/ },
/* 139 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
__webpack_require__(80);
function ActivePlan(joinObserverArray, onNext, onCompleted) {
this._joinObserverArray = joinObserverArray;
this._onNext = onNext;
this._onCompleted = onCompleted;
this._joinObservers = new global.Map();
for (var i = 0, len = this._joinObserverArray.length; i < len; i++) {
var joinObserver = this._joinObserverArray[i];
this._joinObservers.set(joinObserver, joinObserver);
}
}
ActivePlan.prototype.dequeue = function () {
this._joinObservers.forEach(function (v) {
v._queue.shift();
});
};
ActivePlan.prototype.match = function () {
var i,
len,
hasValues = true;
for (i = 0, len = this._joinObserverArray.length; i < len; i++) {
if (this._joinObserverArray[i]._queue.length === 0) {
hasValues = false;
break;
}
}
if (hasValues) {
var firstValues = [],
isCompleted = false;
for (i = 0, len = this._joinObserverArray.length; i < len; i++) {
firstValues.push(this._joinObserverArray[i]._queue[0]);
this._joinObserverArray[i]._queue[0].kind === 'C' && (isCompleted = true);
}
if (isCompleted) {
this._onCompleted();
} else {
this.dequeue();
var values = [];
for (i = 0, len = firstValues.length; i < firstValues.length; i++) {
values.push(firstValues[i].value);
}
this._onNext.apply(this, values);
}
}
};
module.exports = ActivePlan;
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 140 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var SingleAssignmentDisposable = __webpack_require__(17);
var materialize = __webpack_require__(141);
var noop = __webpack_require__(3);
var inherits = __webpack_require__(6);
function JoinObserver(source, onError) {
AbstractObserver.call(this);
this._source = source;
this._onError = onError;
this._queue = [];
this._activePlans = [];
this._subscription = new SingleAssignmentDisposable();
this.isDisposed = false;
}
inherits(JoinObserver, AbstractObserver);
JoinObserver.prototype.next = function (notification) {
if (!this.isDisposed) {
if (notification.kind === 'E') {
return this._onError(notification.error);
}
this._queue.push(notification);
var activePlans = this._activePlans.slice(0);
for (var i = 0, len = activePlans.length; i < len; i++) {
activePlans[i].match();
}
}
};
JoinObserver.prototype.error = noop;
JoinObserver.prototype.completed = noop;
JoinObserver.prototype.addActivePlan = function (activePlan) {
this._activePlans.push(activePlan);
};
JoinObserver.prototype.subscribe = function () {
this._subscription.setDisposable(materialize(this._source).subscribe(this));
};
JoinObserver.prototype.removeActivePlan = function (activePlan) {
this._activePlans.splice(this._activePlans.indexOf(activePlan), 1);
this._activePlans.length === 0 && this.dispose();
};
JoinObserver.prototype.dispose = function () {
AbstractObserver.prototype.dispose.call(this);
if (!this.isDisposed) {
this.isDisposed = true;
this._subscription.dispose();
}
};
module.exports = JoinObserver;
/***/ },
/* 141 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var Notification = __webpack_require__(142);
var inherits = __webpack_require__(6);
function MaterializeObserver(o) {
this._o = o;
AbstractObserver.call(this);
}
inherits(MaterializeObserver, AbstractObserver);
MaterializeObserver.prototype.next = function (x) {
this._o.onNext(Notification.createOnNext(x));
};
MaterializeObserver.prototype.error = function (e) {
this._o.onNext(Notification.createOnError(e));this._o.onCompleted();
};
MaterializeObserver.prototype.completed = function () {
this._o.onNext(Notification.createOnCompleted());this._o.onCompleted();
};
function MaterializeObservable(source) {
this.source = source;
ObservableBase.call(this);
}
inherits(MaterializeObservable, ObservableBase);
MaterializeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MaterializeObserver(o));
};
/**
* Materializes the implicit notifications of an observable sequence as explicit notification values.
* @returns {Observable} An observable sequence containing the materialized notification values from the source sequence.
*/
module.exports = function materialize(source) {
return new MaterializeObservable(source);
};
/***/ },
/* 142 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AnonymousObservable = __webpack_require__(36);
var Scheduler = __webpack_require__(12);
var errors = __webpack_require__(7);
var inherits = __webpack_require__(6);
function Notification() {}
Notification.prototype._accept = function (onNext, onError, onCompleted) {
throw new errors.NotImplementedError();
};
Notification.prototype._acceptObserver = function (onNext, onError, onCompleted) {
throw new errors.NotImplementedError();
};
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
* @param {Function | Observer} observerOrOnNext Function to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Function to invoke for an OnError notification.
* @param {Function} onCompleted Function to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ? this._acceptObserver(observerOrOnNext) : this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var self = this;
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.immediate);
return new AnonymousObservable(function (o) {
return scheduler.schedule(self, function (_, notification) {
notification._acceptObserver(o);
notification.kind === 'N' && o.onCompleted();
});
});
};
function OnNextNotification(value) {
this.value = value;
this.kind = 'N';
}
inherits(OnNextNotification, Notification);
OnNextNotification.prototype._accept = function (onNext) {
return onNext(this.value);
};
OnNextNotification.prototype._acceptObserver = function (o) {
return o.onNext(this.value);
};
OnNextNotification.prototype.toString = function () {
return 'OnNext(' + this.value + ')';
};
function OnErrorNotification(error) {
this.error = error;
this.kind = 'E';
}
inherits(OnErrorNotification, Notification);
OnErrorNotification.prototype._accept = function (onNext, onError) {
return onError(this.error);
};
OnErrorNotification.prototype._acceptObserver = function (o) {
return o.onError(this.error);
};
OnErrorNotification.prototype.toString = function () {
return 'OnError(' + this.error + ')';
};
function OnCompletedNotification() {
this.kind = 'C';
}
inherits(OnCompletedNotification, Notification);
OnCompletedNotification.prototype._accept = function (onNext, onError, onCompleted) {
return onCompleted();
};
OnCompletedNotification.prototype._acceptObserver = function (o) {
return o.onCompleted();
};
OnCompletedNotification.prototype.toString = function () {
return 'OnCompleted()';
};
/**
* Creates an object that represents an OnNext notification to an observer.
* @param {Any} value The value contained in the notification.
* @returns {Notification} The OnNext notification containing the value.
*/
Notification.createOnNext = function (value) {
return new OnNextNotification(value);
};
/**
* Creates an object that represents an OnError notification to an observer.
* @param {Any} error The exception contained in the notification.
* @returns {Notification} The OnError notification containing the exception.
*/
Notification.createOnError = function (error) {
return new OnErrorNotification(error);
};
/**
* Creates an object that represents an OnCompleted notification to an observer.
* @returns {Notification} The OnCompleted notification.
*/
Notification.createOnCompleted = function () {
return new OnCompletedNotification();
};
module.exports = Notification;
/***/ },
/* 143 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var AbstractObserver = __webpack_require__(5);
var EmptyError = __webpack_require__(7).EmptyError;
var isFunction = __webpack_require__(9);
var bindCallback = __webpack_require__(52);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function AverageObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._c = 0;
this._t = 0;
AbstractObserver.call(this);
}
inherits(AverageObserver, AbstractObserver);
AverageObserver.prototype.next = function (x) {
if (this._fn) {
var r = tryCatch(this._fn)(x, this._c++, this._s);
if (r === errorObj) {
return this._o.onError(r.e);
}
this._t += r;
} else {
this._c++;
this._t += x;
}
};
AverageObserver.prototype.error = function (e) {
this._o.onError(e);
};
AverageObserver.prototype.completed = function () {
if (this._c === 0) {
return this._o.onError(new EmptyError());
}
this._o.onNext(this._t / this._c);
this._o.onCompleted();
};
function AverageObservable(source, fn) {
this.source = source;
this._fn = fn;
ObservableBase.call(this);
}
inherits(AverageObservable, ObservableBase);
AverageObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new AverageObserver(o, this._fn, this.source));
};
/**
* Computes the average of an observable sequence of values that are in the sequence or obtained by invoking a transform function on each element of the input sequence if present.
* @param {Function} [selector] A transform function to apply to each element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence containing a single element with the average of the sequence of values.
*/
module.exports = function average(source, keySelector, thisArg) {
var fn;
isFunction(keySelector) && (fn = bindCallback(keySelector, thisArg, 3));
return new AverageObservable(source, fn);
};
/***/ },
/* 144 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var flatMap = __webpack_require__(145);
var window = __webpack_require__(149);
function toArray(x) {
return x.toArray();
}
module.exports = function buffer(source, windowOpeningsOrClosingSelector, windowClosingSelector) {
return flatMap(window(source, windowOpeningsOrClosingSelector, windowClosingSelector), toArray);
};
/***/ },
/* 145 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var FlatMapObservable = __webpack_require__(146);
var mergeAll = __webpack_require__(66);
module.exports = function flatMap(source, selector, resultSelector, thisArg) {
var obs = new FlatMapObservable(source, selector, resultSelector, thisArg);
return mergeAll(obs);
};
/***/ },
/* 146 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var ObservableBase = __webpack_require__(11);
var observableFrom = __webpack_require__(50);
var fromPromise = __webpack_require__(27);
var isPromise = __webpack_require__(28);
var isArrayLike = __webpack_require__(147);
var isIterable = __webpack_require__(148);
var bindCallback = __webpack_require__(52);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function FlatMapObserver(o, selector, resultSelector, source) {
this.i = 0;
this._fn = selector;
this._resFn = resultSelector;
this.source = source;
this._o = o;
AbstractObserver.call(this);
}
inherits(FlatMapObserver, AbstractObserver);
FlatMapObserver.prototype._wrapResult = function (result, x, i) {
return isFunction(this._resFn) ? result.map(function (y, i2) {
return this._resFn(x, y, i, i2);
}, this) : result;
};
FlatMapObserver.prototype.next = function (x) {
var i = this.i++;
var result = tryCatch(this._fn)(x, i, this.source);
if (result === errorObj) {
return this._o.onError(result.e);
}
isPromise(result) && (result = fromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = observableFrom(result));
this._o.onNext(this._wrapResult(result, x, i));
};
FlatMapObserver.prototype.error = function (e) {
this._o.onError(e);
};
FlatMapObserver.prototype.completed = function () {
this._o.onCompleted();
};
function FlatMapObservable(source, fn, resultFn, thisArg) {
this._resFn = isFunction(resultFn) ? resultFn : null;
this._fn = bindCallback(isFunction(fn) ? fn : function () {
return fn;
}, thisArg, 3);
this.source = source;
ObservableBase.call(this);
}
inherits(FlatMapObservable, ObservableBase);
FlatMapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FlatMapObserver(o, this._fn, this._resFn, this));
};
module.exports = FlatMapObservable;
/***/ },
/* 147 */
/***/ function(module, exports) {
'use strict';
module.exports = function isArrayLike(o) {
return o && o.length !== undefined;
};
/***/ },
/* 148 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var $iterator$ = __webpack_require__(51);
module.exports = function isIterable(o) {
return o && o[$iterator$] !== undefined;
};
/***/ },
/* 149 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var CompositeDisposable = __webpack_require__(14);
var RefCountDisposable = __webpack_require__(150);
var SerialDisposable = __webpack_require__(44);
var SingleAssignmentDisposable = __webpack_require__(17);
var AnonymousObservable = __webpack_require__(36);
var Subject = __webpack_require__(57);
var empty = __webpack_require__(41);
var fromPromise = __webpack_require__(27);
var groupJoin = __webpack_require__(151);
var take = __webpack_require__(153);
var addRef = __webpack_require__(152);
var isPromise = __webpack_require__(28);
var isFunction = __webpack_require__(9);
var noop = __webpack_require__(3);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function returnWindow(x, win) {
return win;
}
function observableWindowWithOpenings(source, windowOpenings, windowClosingSelector) {
return groupJoin(windowOpenings, source, windowClosingSelector, empty, returnWindow);
}
function observableWindowWithBoundaries(source, windowBoundaries) {
return new AnonymousObservable(function (o) {
var win = new Subject(),
d = new CompositeDisposable(),
r = new RefCountDisposable(d);
o.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
o.onError(err);
}, function () {
win.onCompleted();
o.onCompleted();
}));
isPromise(windowBoundaries) && (windowBoundaries = fromPromise(windowBoundaries));
d.add(windowBoundaries.subscribe(function () {
win.onCompleted();
win = new Subject();
o.onNext(addRef(win, r));
}, function (err) {
win.onError(err);
o.onError(err);
}, function () {
win.onCompleted();
o.onCompleted();
}));
return r;
}, source);
}
function observableWindowWithClosingSelector(source, windowClosingSelector) {
return new AnonymousObservable(function (o) {
var m = new SerialDisposable(),
d = new CompositeDisposable(m),
r = new RefCountDisposable(d),
win = new Subject();
o.onNext(addRef(win, r));
d.add(source.subscribe(function (x) {
win.onNext(x);
}, function (err) {
win.onError(err);
o.onError(err);
}, function () {
win.onCompleted();
o.onCompleted();
}));
function createWindowClose() {
var windowClose = tryCatch(windowClosingSelector)();
if (windowClose === errorObj) {
return o.onError(windowClose.e);
}
isPromise(windowClose) && (windowClose = fromPromise(windowClose));
var m1 = new SingleAssignmentDisposable();
m.setDisposable(m1);
m1.setDisposable(take(windowClose, 1).subscribe(noop, function (err) {
win.onError(err);
o.onError(err);
}, function () {
win.onCompleted();
win = new Subject();
o.onNext(addRef(win, r));
createWindowClose();
}));
}
createWindowClose();
return r;
}, source);
}
/**
* Projects each element of an observable sequence into zero or more windows.
*
* @param {Mixed} windowOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows).
* @param {Function} [windowClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored.
* @returns {Observable} An observable sequence of windows.
*/
module.exports = function window(source, windowOpeningsOrClosingSelector, windowClosingSelector) {
if (!windowClosingSelector && !isFunction(windowOpeningsOrClosingSelector)) {
return observableWindowWithBoundaries(source, windowOpeningsOrClosingSelector);
}
return isFunction(windowOpeningsOrClosingSelector) ? observableWindowWithClosingSelector(source, windowOpeningsOrClosingSelector) : observableWindowWithOpenings(source, windowOpeningsOrClosingSelector, windowClosingSelector);
};
/***/ },
/* 150 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(13);
function InnerDisposable(disposable) {
this.disposable = disposable;
this.disposable.count++;
this.isInnerDisposed = false;
}
InnerDisposable.prototype.dispose = function () {
if (!this.disposable.isDisposed && !this.isInnerDisposed) {
this.isInnerDisposed = true;
this.disposable.count--;
if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) {
this.disposable.isDisposed = true;
this.disposable.underlyingDisposable.dispose();
}
}
};
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
function RefCountDisposable(disposable) {
this.underlyingDisposable = disposable;
this.isDisposed = false;
this.isPrimaryDisposed = false;
this.count = 0;
}
/**
* Disposes the underlying disposable only when all dependent disposables have been disposed
*/
RefCountDisposable.prototype.dispose = function () {
if (!this.isDisposed && !this.isPrimaryDisposed) {
this.isPrimaryDisposed = true;
if (this.count === 0) {
this.isDisposed = true;
this.underlyingDisposable.dispose();
}
}
};
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
RefCountDisposable.prototype.getDisposable = function () {
return this.isDisposed ? Disposable.empty : new InnerDisposable(this);
};
module.exports = RefCountDisposable;
/***/ },
/* 151 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var AnonymousObservable = __webpack_require__(36); // TODO: Get rid of
var CompositeDisposable = __webpack_require__(14);
var RefCountDisposable = __webpack_require__(150);
var SingleAssignmentDisposable = __webpack_require__(17);
var Subject = __webpack_require__(57);
var addRef = __webpack_require__(152);
var noop = __webpack_require__(3);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
__webpack_require__(80);
module.exports = function groupJoin(left, right, leftDurationSelector, rightDurationSelector, resultSelector) {
return new AnonymousObservable(function (o) {
var group = new CompositeDisposable();
var r = new RefCountDisposable(group);
var leftMap = new global.Map(),
rightMap = new global.Map();
var leftId = 0,
rightId = 0;
var handleError = function (e) {
return function (v) {
v.onError(e);
};
};
group.add(left.subscribe(function (value) {
var s = new Subject();
var id = leftId++;
leftMap.set(id, s);
var result = tryCatch(resultSelector)(value, addRef(s, r));
if (result === errorObj) {
leftMap.forEach(handleError(result.e));
return o.onError(result.e);
}
o.onNext(result);
rightMap.forEach(function (v) {
s.onNext(v);
});
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(leftDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(noop, function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
}, function () {
leftMap['delete'](id) && s.onCompleted();
group.remove(md);
}));
}, function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
}, function () {
o.onCompleted();
}));
group.add(right.subscribe(function (value) {
var id = rightId++;
rightMap.set(id, value);
var md = new SingleAssignmentDisposable();
group.add(md);
var duration = tryCatch(rightDurationSelector)(value);
if (duration === errorObj) {
leftMap.forEach(handleError(duration.e));
return o.onError(duration.e);
}
md.setDisposable(duration.take(1).subscribe(noop, function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
}, function () {
rightMap['delete'](id);
group.remove(md);
}));
leftMap.forEach(function (v) {
v.onNext(value);
});
}, function (e) {
leftMap.forEach(handleError(e));
o.onError(e);
}));
return r;
}, left);
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 152 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(11);
var BinaryDisposable = __webpack_require__(24);
var inherits = __webpack_require__(6);
function AddRefObservable(xs, r) {
this._xs = xs;
this._r = r;
ObservableBase.call(this);
}
inherits(AddRefObservable, ObservableBase);
AddRefObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(this._r.getDisposable(), this._xs.subscribe(o));
};
module.exports = function addRef(xs, r) {
return new AddRefObservable(xs, r);
};
/***/ },
/* 153 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var ObservableBase = __webpack_require__(11);
var empty = __webpack_require__(41);
var errors = __webpack_require__(7);
var inherits = __webpack_require__(6);
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeObserver.prototype.completed = function () {
this._o.onCompleted();
};
function TakeObservable(source, count) {
this.source = source;
this._count = count;
ObservableBase.call(this);
}
inherits(TakeObservable, ObservableBase);
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0;
},
/**
* Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
*/
onCompleted: function () {
var i;
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
var os = cloneArray(this.observers),
len = os.length;
if (this.hasValue) {
for (i = 0; i < len; i++) {
var o = os[i];
o.onNext(this.value);
o.onCompleted();
}
} else {
for (i = 0; i < len; i++) {
os[i].onCompleted();
}
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the error.
* @param {Mixed} error The Error to send to all observers.
*/
onError: function (error) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
* @param {Mixed} value The value to store in the subject.
*/
onNext: function (value) {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.value = value;
this.hasValue = true;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.error = null;
this.value = null;
}
});
module.exports = AsyncSubject;
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var noop = __webpack_require__(3);
var isFunction = __webpack_require__(9);
var ObjectDisposedError = __webpack_require__(7).ObjectDisposedError;
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
function Disposable(action) {
this.isDisposed = false;
this.action = action || noop;
}
/** Performs the task of cleaning up resources. */
Disposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.action();
this.isDisposed = true;
}
};
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
Disposable.create = function (action) {
return new Disposable(action);
};
/**
* Gets the disposable that does nothing when disposed.
*/
Disposable.empty = { dispose: noop };
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
Disposable.isDisposable = function (d) {
return d && isFunction(d.dispose);
};
Disposable.checkDisposed = function (disposable) {
if (disposable.isDisposed) {
throw new ObjectDisposedError();
}
};
Disposable._fixup = function (result) {
return Disposable.isDisposable(result) ? result : Disposable.empty;
};
module.exports = Disposable;
/***/ },
/* 13 */
/***/ function(module, exports) {
'use strict';
function InnerSubscription(s, o) {
this._s = s;
this._o = o;
}
InnerSubscription.prototype.dispose = function () {
if (!this._s.isDisposed && this._o !== null) {
var idx = this._s.observers.indexOf(this._o);
this._s.observers.splice(idx, 1);
this._o = null;
}
};
module.exports = InnerSubscription;
/***/ },
/* 14 */
/***/ function(module, exports) {
'use strict';
module.exports = function addProperties() {
var obj = arguments[0];
for (var sources = [], i = 1, len = arguments.length; i < len; i++) {
sources.push(arguments[i]);
}
for (var idx = 0, ln = sources.length; idx < ln; idx++) {
var source = sources[idx];
for (var prop in source) {
obj[prop] = source[prop];
}
}
};
/***/ },
/* 15 */
/***/ function(module, exports) {
'use strict';
module.exports = function cloneArray(arr) {
var len = arr.length,
a = new Array(len);
for (var i = 0; i < len; i++) {
a[i] = arr[i];
}
return a;
};
/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AnonymousObservable = __webpack_require__(17);
function createAsObservable(source) {
return function subscribe(o) {
return source.subscribe(o);
};
}
/**
* Hides the identity of an observable sequence.
* @returns {Observable} An observable sequence that hides the identity of the source sequence.
*/
module.exports = function asObservable(source) {
return new AnonymousObservable(createAsObservable(source), source);
};
/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var inherits = __webpack_require__(6);
var isFunction = __webpack_require__(9);
var Observable = __webpack_require__(8);
var Disposable = __webpack_require__(12);
var AutoDetachObserver = __webpack_require__(18);
var Scheduler = __webpack_require__(21);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
// Fix subscriber to check for undefined or function returned to decorate as Disposable
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber : isFunction(subscriber) ? Disposable.create(subscriber) : Disposable.empty;
}
function setDisposable(s, state) {
var ado = state[0],
self = state[1];
var sub = tryCatch(self.__subscribe).call(self, ado);
if (sub === errorObj && !ado.fail(sub.e)) {
thrower(sub.e);
}
ado.setDisposable(fixSubscriber(sub));
}
function AnonymousObservable(subscribe, parent) {
this.source = parent;
this.__subscribe = subscribe;
Observable.call(this);
}
inherits(AnonymousObservable, Observable);
AnonymousObservable.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o),
state = [ado, this];
if (Scheduler.queue.scheduleRequired()) {
Scheduler.queue.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
module.exports = AnonymousObservable;
/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var SingleAssignmentDisposable = __webpack_require__(19);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function AutoDetachObserver(observer) {
AbstractObserver.call(this);
this.observer = observer;
this.m = new SingleAssignmentDisposable();
}
inherits(AutoDetachObserver, AbstractObserver);
AutoDetachObserver.prototype.next = function (value) {
var result = tryCatch(this.observer.onNext).call(this.observer, value);
if (result === errorObj) {
this.dispose();
thrower(result.e);
}
};
AutoDetachObserver.prototype.error = function (err) {
var result = tryCatch(this.observer.onError).call(this.observer, err);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserver.prototype.completed = function () {
var result = tryCatch(this.observer.onCompleted).call(this.observer);
this.dispose();
result === errorObj && thrower(result.e);
};
AutoDetachObserver.prototype.setDisposable = function (value) {
this.m.setDisposable(value);
};
AutoDetachObserver.prototype.getDisposable = function () {
return this.m.getDisposable();
};
AutoDetachObserver.prototype.dispose = function () {
AbstractObserver.prototype.dispose.call(this);
this.m.dispose();
};
module.exports = AutoDetachObserver;
/***/ },
/* 19 */
/***/ function(module, exports) {
'use strict';
function SingleAssignmentDisposable() {
this.isDisposed = false;
this._current = null;
}
SingleAssignmentDisposable.prototype.getDisposable = function () {
return this._current;
};
SingleAssignmentDisposable.prototype.setDisposable = function (value) {
if (this._current) {
throw new Error('Disposable has already been assigned');
}
var shouldDispose = this.isDisposed;
!shouldDispose && (this._current = value);
shouldDispose && value && value.dispose();
};
SingleAssignmentDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this._current;
this._current = null;
old && old.dispose();
}
};
module.exports = SingleAssignmentDisposable;
/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isFunction = __webpack_require__(9);
var errorObj = module.exports.errorObj = { e: {} };
function tryCatcherGen(tryCatchTarget) {
return function tryCatcher() {
try {
return tryCatchTarget.apply(this, arguments);
} catch (e) {
errorObj.e = e;
return errorObj;
}
};
}
module.exports.tryCatch = function tryCatch(fn) {
if (!isFunction(fn)) {
throw new TypeError('fn must be a function');
}
return tryCatcherGen(fn);
};
module.exports.thrower = function thrower(e) {
throw e;
};
/***/ },
/* 21 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var errors = __webpack_require__(7);
var Disposable = __webpack_require__(12);
var CompositeDisposable = __webpack_require__(22);
function Scheduler() {}
/** Determines whether the given object is a scheduler */
Scheduler.isScheduler = function (s) {
return s instanceof Scheduler;
};
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.schedule = function (state, action) {
throw new errors.NotImplementedError();
};
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.scheduleFuture = function (state, dueTime, action) {
var dt = dueTime;
dt instanceof Date && (dt = dt - this.now());
dt = Scheduler.normalize(dt);
if (dt === 0) {
return this.schedule(state, action);
}
return this._scheduleFuture(state, dt, action);
};
Scheduler.prototype._scheduleFuture = function (state, dueTime, action) {
throw new errors.NotImplementedError();
};
function PeriodicDisposable(id) {
this._id = id;
this.isDisposed = false;
}
PeriodicDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
global.clearInterval(this._id);
}
};
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
Scheduler.prototype.schedulePeriodic = function (state, period, action) {
if (typeof global.setInterval === 'undefined') {
throw new errors.NotSupportedError();
}
period = Scheduler.normalize(period);
var s = state,
id = global.setInterval(function () {
s = action(s);
}, period);
return new PeriodicDisposable(id);
};
function invokeRecImmediate(scheduler, pair) {
var state = pair[0],
action = pair[1],
group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2) {
var isAdded = false,
isDone = false;
var d = scheduler.schedule(state2, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return Disposable.empty;
}
}
}
function invokeRecDate(scheduler, pair) {
var state = pair[0],
action = pair[1],
group = new CompositeDisposable();
action(state, innerAction);
return group;
function innerAction(state2, dueTime1) {
var isAdded = false,
isDone = false;
var d = scheduler.scheduleFuture(state2, dueTime1, scheduleWork);
if (!isDone) {
group.add(d);
isAdded = true;
}
function scheduleWork(_, state3) {
if (isAdded) {
group.remove(d);
} else {
isDone = true;
}
action(state3, innerAction);
return Disposable.empty;
}
}
}
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.scheduleRecursive = function (state, action) {
return this.schedule([state, action], invokeRecImmediate);
};
/**
* Schedules an action to be executed recursively after a specified relative or absolute due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number | Date} dueTime Relative or absolute time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
Scheduler.prototype.scheduleRecursiveFuture = function (state, dueTime, action) {
return this.scheduleFuture([state, action], dueTime, invokeRecDate);
};
var defaultNow = function () {
return !!Date.now ? Date.now : function () {
return +new Date();
};
}();
/** Gets the current time according to the local machine's system clock. */
Scheduler.now = defaultNow;
/** Gets the current time according to the local machine's system clock. */
Scheduler.prototype.now = defaultNow;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
Scheduler.normalize = function (timeSpan) {
timeSpan < 0 && (timeSpan = 0);
return timeSpan;
};
module.exports = Scheduler;
var CurrentThreadScheduler = __webpack_require__(23);
var ImmediateScheduler = __webpack_require__(27);
var DefaultScheduler = __webpack_require__(28);
var CatchScheduler = __webpack_require__(31);
Scheduler.queue = Scheduler.currentThread = new CurrentThreadScheduler();
Scheduler.async = Scheduler['default'] = Scheduler.timeout = new DefaultScheduler();
Scheduler.immediate = new ImmediateScheduler();
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
Scheduler.prototype['catch'] = function (handler) {
return new CatchScheduler(this, handler);
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 22 */
/***/ function(module, exports) {
'use strict';
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
function CompositeDisposable() {
var args = [],
i,
len;
if (Array.isArray(arguments[0])) {
args = arguments[0];
len = args.length;
} else {
len = arguments.length;
args = new Array(len);
for (i = 0; i < len; i++) {
args[i] = arguments[i];
}
}
this.disposables = args;
this.isDisposed = false;
this.length = args.length;
}
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
CompositeDisposable.prototype.add = function (item) {
if (this.isDisposed) {
item.dispose();
} else {
this.disposables.push(item);
this.length++;
}
};
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
CompositeDisposable.prototype.remove = function (item) {
var shouldDispose = false;
if (!this.isDisposed) {
var idx = this.disposables.indexOf(item);
if (idx !== -1) {
shouldDispose = true;
this.disposables.splice(idx, 1);
this.length--;
item.dispose();
}
}
return shouldDispose;
};
/**
* Disposes all disposables in the group and removes them from the group.
*/
CompositeDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var len = this.disposables.length,
currentDisposables = new Array(len);
for (var i = 0; i < len; i++) {
currentDisposables[i] = this.disposables[i];
}
this.disposables = [];
this.length = 0;
for (i = 0; i < len; i++) {
currentDisposables[i].dispose();
}
}
};
module.exports = CompositeDisposable;
/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Scheduler = __webpack_require__(21);
var ScheduledItem = __webpack_require__(24);
var PriorityQueue = __webpack_require__(26);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
var inherits = __webpack_require__(6);
function CurrentThreadScheduler() {
Scheduler.call(this);
}
CurrentThreadScheduler.queue = null;
inherits(CurrentThreadScheduler, Scheduler);
function runTrampoline() {
while (CurrentThreadScheduler.queue.length > 0) {
var item = CurrentThreadScheduler.queue.dequeue();
!item.isCancelled() && item.invoke();
}
}
CurrentThreadScheduler.prototype.schedule = function (state, action) {
var si = new ScheduledItem(this, state, action, this.now());
if (!CurrentThreadScheduler.queue) {
CurrentThreadScheduler.queue = new PriorityQueue(4);
CurrentThreadScheduler.queue.enqueue(si);
var result = tryCatch(runTrampoline)();
CurrentThreadScheduler.queue = null;
if (result === errorObj) {
thrower(result.e);
}
} else {
CurrentThreadScheduler.queue.enqueue(si);
}
return si.disposable;
};
CurrentThreadScheduler.prototype.scheduleRequired = function () {
return !CurrentThreadScheduler.queue;
};
module.exports = CurrentThreadScheduler;
/***/ },
/* 24 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(12);
var SingleAssignmentDisposable = __webpack_require__(19);
var cmp = __webpack_require__(25);
function ScheduledItem(scheduler, state, action, dueTime, comparer) {
this.scheduler = scheduler;
this.state = state;
this.action = action;
this.dueTime = dueTime;
this.comparer = comparer || cmp;
this.disposable = new SingleAssignmentDisposable();
}
ScheduledItem.prototype.invoke = function () {
this.disposable.setDisposable(this.invokeCore());
};
ScheduledItem.prototype.compareTo = function (other) {
return this.comparer(this.dueTime, other.dueTime);
};
ScheduledItem.prototype.isCancelled = function () {
return this.disposable.isDisposed;
};
ScheduledItem.prototype.invokeCore = function () {
return Disposable._fixup(this.action(this.scheduler, this.state));
};
module.exports = ScheduledItem;
/***/ },
/* 25 */
/***/ function(module, exports) {
'use strict';
module.exports = function comparer(x, y) {
if (x > y) {
return 1;
}
if (y > x) {
return -1;
}
return 0;
};
/***/ },
/* 26 */
/***/ function(module, exports) {
'use strict';
function IndexedItem(id, value) {
this.id = id;
this.value = value;
}
IndexedItem.prototype.compareTo = function (other) {
var c = this.value.compareTo(other.value);
c === 0 && (c = this.id - other.id);
return c;
};
function PriorityQueue(capacity) {
this.items = new Array(capacity);
this.length = 0;
}
PriorityQueue.prototype.isHigherPriority = function (left, right) {
return this.items[left].compareTo(this.items[right]) < 0;
};
PriorityQueue.prototype.percolate = function (index) {
if (index >= this.length || index < 0) {
return;
}
var parent = index - 1 >> 1;
if (parent < 0 || parent === index) {
return;
}
if (this.isHigherPriority(index, parent)) {
var temp = this.items[index];
this.items[index] = this.items[parent];
this.items[parent] = temp;
this.percolate(parent);
}
};
PriorityQueue.prototype.heapify = function (index) {
+index || (index = 0);
if (index >= this.length || index < 0) {
return;
}
var left = 2 * index + 1,
right = 2 * index + 2,
first = index;
if (left < this.length && this.isHigherPriority(left, first)) {
first = left;
}
if (right < this.length && this.isHigherPriority(right, first)) {
first = right;
}
if (first !== index) {
var temp = this.items[index];
this.items[index] = this.items[first];
this.items[first] = temp;
this.heapify(first);
}
};
PriorityQueue.prototype.peek = function () {
return this.items[0].value;
};
PriorityQueue.prototype.removeAt = function (index) {
this.items[index] = this.items[--this.length];
this.items[this.length] = undefined;
this.heapify();
};
PriorityQueue.prototype.dequeue = function () {
var result = this.peek();
this.removeAt(0);
return result;
};
PriorityQueue.prototype.enqueue = function (item) {
var index = this.length++;
this.items[index] = new IndexedItem(PriorityQueue.count++, item);
this.percolate(index);
};
PriorityQueue.prototype.remove = function (item) {
for (var i = 0; i < this.length; i++) {
if (this.items[i].value === item) {
this.removeAt(i);
return true;
}
}
return false;
};
PriorityQueue.count = 0;
module.exports = PriorityQueue;
/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Scheduler = __webpack_require__(21);
var Disposable = __webpack_require__(12);
var inherits = __webpack_require__(6);
function ImmediateScheduler() {
Scheduler.call(this);
}
inherits(ImmediateScheduler, Scheduler);
ImmediateScheduler.prototype.schedule = function (state, action) {
return Disposable._fixup(action(this, state));
};
module.exports = ImmediateScheduler;
/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global, process) {'use strict';
var Disposable = __webpack_require__(12);
var BinaryDisposable = __webpack_require__(30);
var SingleAssignmentDisposable = __webpack_require__(19);
var Scheduler = __webpack_require__(21);
var isFunction = __webpack_require__(9);
var noop = __webpack_require__(3);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
var inherits = __webpack_require__(6);
var scheduleMethod, clearMethod;
(function () {
var nextHandle = 1,
tasksByHandle = {},
currentlyRunning = false;
clearMethod = function (handle) {
delete tasksByHandle[handle];
};
function runTask(handle) {
if (currentlyRunning) {
global.setTimeout(function () {
runTask(handle);
}, 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunning = true;
var result = tryCatch(task)();
clearMethod(handle);
currentlyRunning = false;
if (result === errorObj) {
thrower(result.e);
}
}
}
}
var setImmediate = global.setImmediate;
function postMessageSupported() {
// Ensure not in a worker
if (!global.postMessage || global.importScripts) {
return false;
}
var isAsync = false,
oldHandler = global.onmessage;
// Test for async
global.onmessage = function () {
isAsync = true;
};
global.postMessage('', '*');
global.onmessage = oldHandler;
return isAsync;
}
// Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout
if (isFunction(setImmediate)) {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
setImmediate(function () {
runTask(id);
});
return id;
};
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
process.nextTick(function () {
runTask(id);
});
return id;
};
} else if (postMessageSupported()) {
var MSG_PREFIX = 'ms.rx.schedule' + Math.random();
var onGlobalPostMessage = function (event) {
// Only if we're a match to avoid any other global events
if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) {
runTask(event.data.substring(MSG_PREFIX.length));
}
};
global.addEventListener('message', onGlobalPostMessage, false);
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
global.postMessage(MSG_PREFIX + id, '*');
return id;
};
} else if (!!global.MessageChannel) {
var channel = new global.MessageChannel();
channel.port1.onmessage = function (e) {
runTask(e.data);
};
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
channel.port2.postMessage(id);
return id;
};
} else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
scheduleMethod = function (action) {
var scriptElement = global.document.createElement('script');
var id = nextHandle++;
tasksByHandle[id] = action;
scriptElement.onreadystatechange = function () {
runTask(id);
scriptElement.onreadystatechange = null;
scriptElement.parentNode.removeChild(scriptElement);
scriptElement = null;
};
global.document.documentElement.appendChild(scriptElement);
return id;
};
} else {
scheduleMethod = function (action) {
var id = nextHandle++;
tasksByHandle[id] = action;
global.setTimeout(function () {
runTask(id);
}, 0);
return id;
};
}
})();
/**
* Gets a scheduler that schedules work via a timed callback based upon platform.
*/
function DefaultScheduler() {
Scheduler.call(this);
}
inherits(DefaultScheduler, Scheduler);
function scheduleAction(disposable, action, scheduler, state) {
return function schedule() {
disposable.setDisposable(Disposable._fixup(action(scheduler, state)));
};
}
function ClearDisposable(method, id) {
this._id = id;
this._method = method;
this.isDisposed = false;
}
ClearDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
this._method.call(null, this._id);
}
};
DefaultScheduler.prototype.schedule = function (state, action) {
var disposable = new SingleAssignmentDisposable(),
id = scheduleMethod(scheduleAction(disposable, action, this, state));
return new BinaryDisposable(disposable, new ClearDisposable(clearMethod, id));
};
DefaultScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
if (dueTime === 0) {
return this.schedule(state, action);
}
var disposable = new SingleAssignmentDisposable(),
id = global.setTimeout(scheduleAction(disposable, action, this, state), dueTime);
return new BinaryDisposable(disposable, new ClearDisposable(global.clearTimeout, id));
};
module.exports = DefaultScheduler;
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(29)))
/***/ },
/* 29 */
/***/ function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = setTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
clearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
setTimeout(drainQueue, 0);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ },
/* 30 */
/***/ function(module, exports) {
'use strict';
function BinaryDisposable(first, second) {
this._first = first;
this._second = second;
this.isDisposed = false;
}
BinaryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old1 = this._first;
this._first = null;
old1 && old1.dispose();
var old2 = this._second;
this._second = null;
old2 && old2.dispose();
}
};
module.exports = BinaryDisposable;
/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Scheduler = __webpack_require__(21);
var Disposable = __webpack_require__(12);
var SingleAssignmentDisposable = __webpack_require__(19);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function CatchScheduler(scheduler, handler) {
this._scheduler = scheduler;
this._handler = handler;
this._recursiveOriginal = null;
this._recursiveWrapper = null;
Scheduler.call(this);
}
inherits(CatchScheduler, Scheduler);
CatchScheduler.prototype.schedule = function (state, action) {
return this._scheduler.schedule(state, this._wrap(action));
};
CatchScheduler.prototype._scheduleFuture = function (state, dueTime, action) {
return this._scheduler.schedule(state, dueTime, this._wrap(action));
};
CatchScheduler.prototype.now = function () {
return this._scheduler.now();
};
CatchScheduler.prototype._clone = function (scheduler) {
return new CatchScheduler(scheduler, this._handler);
};
CatchScheduler.prototype._wrap = function (action) {
var parent = this;
return function (self, state) {
var res = tryCatch(action)(parent._getRecursiveWrapper(self), state);
if (res === errorObj) {
if (!parent._handler(res.e)) {
thrower(res.e);
}
return Disposable.empty;
}
return Disposable._fixup(res);
};
};
CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) {
if (this._recursiveOriginal !== scheduler) {
this._recursiveOriginal = scheduler;
var wrapper = this._clone(scheduler);
wrapper._recursiveOriginal = scheduler;
wrapper._recursiveWrapper = wrapper;
this._recursiveWrapper = wrapper;
}
return this._recursiveWrapper;
};
CatchScheduler.prototype.schedulePeriodic = function (state, period, action) {
var self = this,
failed = false,
d = new SingleAssignmentDisposable();
d.setDisposable(this._scheduler.schedulePeriodic(state, period, function (state1) {
if (failed) {
return null;
}
var res = tryCatch(action)(state1);
if (res === errorObj) {
failed = true;
if (!self._handler(res.e)) {
thrower(res.e);
}
d.dispose();
return null;
}
return res;
}));
return d;
};
module.exports = CatchScheduler;
/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AsyncSubject = __webpack_require__(11);
var asObservable = __webpack_require__(16);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function createNodeHandler(o, ctx, selector) {
return function handler() {
var err = arguments[0];
if (err) {
return o.onError(err);
}
var len = arguments.length,
results = [];
for (var i = 1; i < len; i++) {
results[i - 1] = arguments[i];
}
if (isFunction(selector)) {
results = tryCatch(selector).apply(ctx, results);
if (results === errorObj) {
return o.onError(results.e);
}
o.onNext(results);
} else {
if (results.length <= 1) {
o.onNext(results[0]);
} else {
o.onNext(results);
}
}
o.onCompleted();
};
}
function createNodeObservable(fn, ctx, selector, args) {
var o = new AsyncSubject();
args.push(createNodeHandler(o, ctx, selector));
var res = tryCatch(fn).apply(ctx, args);
if (res === errorObj) {
o.onError(res.e);
}
return asObservable(o);
}
/**
* Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format.
* @param {Function} fn The function to call
* @param {Mixed} [ctx] The context for the func parameter to be executed. If not specified, defaults to undefined.
* @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
* @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array.
*/
module.exports = function bindNodeCallback(fn, ctx, selector) {
return function () {
typeof ctx === 'undefined' && (ctx = this);
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return createNodeObservable(fn, ctx, selector, args);
};
};
/***/ },
/* 33 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var Scheduler = __webpack_require__(21);
var NAryDisposable = __webpack_require__(35);
var SerialDisposable = __webpack_require__(36);
var SingleAssignmentDisposable = __webpack_require__(19);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var inherits = __webpack_require__(6);
function CatchObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(CatchObserver, AbstractObserver);
CatchObserver.prototype.next = function (x) {
this._state.o.onNext(x);
};
CatchObserver.prototype.error = function (e) {
this._state.lastError = e;this._recurse(this._state);
};
CatchObserver.prototype.completed = function () {
this._state.o.onCompleted();
};
function CatchObservable(sources) {
this.sources = sources;
ObservableBase.call(this);
}
inherits(CatchObservable, ObservableBase);
function scheduleMethod(state, recurse) {
if (state.isDisposed) {
return;
}
if (state.i < state.sources.length) {
var currentValue = state.sources[state.i++];
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new CatchObserver(state, recurse)));
} else {
if (state.lastError !== null) {
state.o.onError(state.lastError);
} else {
state.o.onCompleted();
}
}
}
function IsDisposedDisposable(s) {
this._s = s;
}
IsDisposedDisposable.prototype.dispose = function () {
!this._s.isDisposed && (this._s.isDisposed = true);
};
CatchObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
sources: this.sources,
i: 0,
subscription: subscription,
lastError: null,
o: o
};
var cancelable = Scheduler.queue.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, new IsDisposedDisposable(state)]);
};
module.exports = function catch_() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return new CatchObservable(args);
};
/***/ },
/* 34 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var inherits = __webpack_require__(6);
var isFunction = __webpack_require__(9);
var errors = __webpack_require__(7);
var Observable = __webpack_require__(8);
var Scheduler = __webpack_require__(21);
var Disposable = __webpack_require__(12);
var AutoDetachObserver = __webpack_require__(18);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function fixSubscriber(subscriber) {
return subscriber && isFunction(subscriber.dispose) ? subscriber : isFunction(subscriber) ? Disposable.create(subscriber) : Disposable.empty;
}
function setDisposable(s, state) {
var ado = state[0],
self = state[1];
var sub = tryCatch(self.subscribeCore).call(self, ado);
if (sub === errorObj && !ado.fail(sub.e)) {
thrower(sub.e);
}
ado.setDisposable(fixSubscriber(sub));
}
function ObservableBase() {
Observable.call(this);
}
inherits(ObservableBase, Observable);
ObservableBase.prototype._subscribe = function (o) {
var ado = new AutoDetachObserver(o),
state = [ado, this];
if (Scheduler.queue.scheduleRequired()) {
Scheduler.queue.schedule(state, setDisposable);
} else {
setDisposable(null, state);
}
return ado;
};
ObservableBase.prototype.subscribeCore = function () {
throw new errors.NotImplementedError();
};
module.exports = ObservableBase;
/***/ },
/* 35 */
/***/ function(module, exports) {
'use strict';
function NAryDisposable(disposables) {
this._disposables = disposables;
this.isDisposed = false;
}
NAryDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
for (var i = 0, len = this._disposables.length; i < len; i++) {
this._disposables[i].dispose();
}
this._disposables.length = 0;
}
};
module.exports = NAryDisposable;
/***/ },
/* 36 */
/***/ function(module, exports) {
'use strict';
function SerialDisposable() {
this.isDisposed = false;
this._current = null;
}
SerialDisposable.prototype.getDisposable = function () {
return this._current;
};
SerialDisposable.prototype.setDisposable = function (value) {
var shouldDispose = this.isDisposed;
if (!shouldDispose) {
var old = this._current;
this._current = value;
old && old.dispose();
}
shouldDispose && value && value.dispose();
};
SerialDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this.isDisposed = true;
var old = this._current;
this._current = null;
old && old.dispose();
}
};
module.exports = SerialDisposable;
/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var Scheduler = __webpack_require__(21);
var SingleAssignmentDisposable = __webpack_require__(19);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
function FromPromiseObservable(p, s) {
this._p = p;
this._s = s;
ObservableBase.call(this);
}
inherits(FromPromiseObservable, ObservableBase);
function scheduleNext(s, state) {
var o = state[0],
data = state[1];
o.onNext(data);
o.onCompleted();
}
function scheduleError(s, state) {
var o = state[0],
err = state[1];
o.onError(err);
}
FromPromiseObservable.prototype.subscribeCore = function (o) {
var sad = new SingleAssignmentDisposable(),
self = this,
p = self._p;
if (isFunction(p)) {
p = tryCatch(p)();
if (p === errorObj) {
o.onError(p.e);
return sad;
}
}
p.then(function (data) {
sad.setDisposable(self._s.schedule([o, data], scheduleNext));
}, function (err) {
sad.setDisposable(self._s.schedule([o, err], scheduleError));
});
return sad;
};
/**
* Converts a Promise to an Observable sequence
* @param {Promise|Function} An ES6 Compliant promise or a function that returns one
* @returns {Observable} An Observable sequence which wraps the existing promise success and failure.
*/
module.exports = function fromPromise(promise, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return new FromPromiseObservable(promise, scheduler);
};
/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var isFunction = __webpack_require__(9);
module.exports = function isPromise(p) {
return p && isFunction(p.then);
};
/***/ },
/* 39 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var Scheduler = __webpack_require__(21);
var Disposable = __webpack_require__(12);
var NAryDisposable = __webpack_require__(35);
var SerialDisposable = __webpack_require__(36);
var SingleAssignmentDisposable = __webpack_require__(19);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var inherits = __webpack_require__(6);
function ConcatObserver(s, fn) {
this._s = s;
this._fn = fn;
AbstractObserver.call(this);
}
inherits(ConcatObserver, AbstractObserver);
ConcatObserver.prototype.next = function (x) {
this._s.o.onNext(x);
};
ConcatObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
ConcatObserver.prototype.completed = function () {
this._s.i++;this._fn(this._s);
};
function ConcatObservable(sources) {
this._sources = sources;
ObservableBase.call(this);
}
inherits(ConcatObservable, ObservableBase);
function scheduleRecursive(state, recurse) {
if (state.disposable.isDisposed) {
return;
}
if (state.i === state.sources.length) {
return state.o.onCompleted();
}
// Check if promise
var currentValue = state.sources[state.i];
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new ConcatObserver(state, recurse)));
}
ConcatObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var disposable = Disposable.create();
var state = {
o: o,
i: 0,
subscription: subscription,
disposable: disposable,
sources: this._sources
};
var cancelable = Scheduler.immediate.scheduleRecursive(state, scheduleRecursive);
return new NAryDisposable([subscription, disposable, cancelable]);
};
/**
* Concatenates all the observable sequences.
* @param {Array | Arguments} args Arguments or an array to concat to the observable sequence.
* @returns {Observable} An observable sequence that contains the elements of each given sequence, in sequential order.
*/
module.exports = function concat() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return new ConcatObservable(args);
};
/***/ },
/* 40 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AnonymousObservable = __webpack_require__(17);
/**
* Creates an observable sequence from a specified subscribe method implementation.
* @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable.
* @returns {Observable} The observable sequence with the specified implementation for the Subscribe method.
*/
module.exports = function create(subscribe, parent) {
return new AnonymousObservable(subscribe, parent);
};
/***/ },
/* 41 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var Disposable = __webpack_require__(12);
var Scheduler = __webpack_require__(21);
var inherits = __webpack_require__(6);
function scheduleItem(s, state) {
state.onCompleted();
return Disposable.empty;
}
function EmptyObservable(scheduler) {
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(EmptyObservable, ObservableBase);
EmptyObservable.prototype.subscribeCore = function (o) {
return this.scheduler === Scheduler.immediate ? scheduleItem(null, o) : this._scheduler.schedule(o, scheduleItem);
};
var EMPTY_OBSERVABLE = new EmptyObservable(Scheduler.immediate);
/**
* Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message.
*
* @example
* var res = Rx.Observable.empty();
* var res = Rx.Observable.empty(Rx.Scheduler.timeout);
* @param {Scheduler} [scheduler] Scheduler to send the termination call on.
* @returns {Observable} An observable sequence with no elements.
*/
module.exports = function empty(scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.immediate);
return scheduler === Scheduler.immediate ? EMPTY_OBSERVABLE : new EmptyObservable(scheduler);
};
/***/ },
/* 42 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var ObservableBase = __webpack_require__(34);
var Scheduler = __webpack_require__(21);
var isFunction = __webpack_require__(9);
var $iterator$ = __webpack_require__(43);
var bindCallback = __webpack_require__(44);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var doneEnumerator = { done: true, value: undefined };
var maxSafeInteger = Math.pow(2, 53) - 1;
function numberIsFinite(value) {
return typeof value === 'number' && global.isFinite(value);
}
function sign(value) {
var number = +value;
if (number === 0) {
return number;
}
if (isNaN(number)) {
return number;
}
return number < 0 ? -1 : 1;
}
function toLength(o) {
var len = +o.length;
if (isNaN(len)) {
return 0;
}
if (len === 0 || !numberIsFinite(len)) {
return len;
}
len = sign(len) * Math.floor(Math.abs(len));
if (len <= 0) {
return 0;
}
if (len > maxSafeInteger) {
return maxSafeInteger;
}
return len;
}
function StringIterator(s) {
this._s = s;
this._l = s.length;
this._i = 0;
}
StringIterator.prototype[$iterator$] = function () {
return this;
};
StringIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._s.charAt(this._i++) } : doneEnumerator;
};
function StringIterable(s) {
this._s = s;
}
StringIterable.prototype[$iterator$] = function () {
return new StringIterator(this._s);
};
function ArrayIterator(a) {
this._a = a;
this._l = toLength(a);
this._i = 0;
}
ArrayIterator.prototype[$iterator$] = function () {
return this;
};
ArrayIterator.prototype.next = function () {
return this._i < this._l ? { done: false, value: this._a[this._i++] } : doneEnumerator;
};
function ArrayIterable(a) {
this._a = a;
}
ArrayIterable.prototype[$iterator$] = function () {
return new ArrayIterator(this._a);
};
function getIterable(o) {
var i = o[$iterator$],
it;
if (!i && typeof o === 'string') {
it = new StringIterable(o);
return it[$iterator$]();
}
if (!i && o.length !== undefined) {
it = new ArrayIterable(o);
return it[$iterator$]();
}
if (!i) {
throw new TypeError('Object is not iterable');
}
return o[$iterator$]();
}
function FromObservable(iterable, fn, scheduler) {
this._iterable = iterable;
this._fn = fn;
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(FromObservable, ObservableBase);
function scheduleRecursive(o, it, fn) {
return function loopRecursive(i, recurse) {
var next = tryCatch(it.next).call(it);
if (next === errorObj) {
return o.onError(next.e);
}
if (next.done) {
return o.onCompleted();
}
var result = next.value;
if (isFunction(fn)) {
result = tryCatch(fn)(result, i);
if (result === errorObj) {
return o.onError(result.e);
}
}
o.onNext(result);
recurse(i + 1);
};
}
FromObservable.prototype.subscribeCore = function (o) {
var list = Object(this._iterable),
it = getIterable(list);
return this._scheduler.scheduleRecursive(0, scheduleRecursive(o, it, this._fn));
};
/**
* This method creates a new Observable sequence from an array-like or iterable object.
* @param {Any} arrayLike An array-like or iterable object to convert to an Observable sequence.
* @param {Function} [mapFn] Map function to call on every element of the array.
* @param {Any} [thisArg] The context to use calling the mapFn if provided.
* @param {Scheduler} [scheduler] Optional scheduler to use for scheduling. If not provided, defaults to Scheduler.currentThread.
*/
module.exports = function (iterable, mapFn, thisArg, scheduler) {
if (iterable == null) {
throw new Error('iterable cannot be null.');
}
if (mapFn && !isFunction(mapFn)) {
throw new Error('mapFn when provided must be a function');
}
var mapper;
if (mapFn) {
mapper = bindCallback(mapFn, thisArg, 2);
}
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new FromObservable(iterable, mapper, scheduler);
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 43 */
/***/ function(module, exports) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
// Shim in iterator support
var $iterator$ = typeof global.Symbol === 'function' && global.Symbol.iterator || '_es6shim_iterator_';
// Bug for mozilla version
if (global.Set && typeof new global.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
module.exports = $iterator$;
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 44 */
/***/ function(module, exports) {
'use strict';
module.exports = function bindCallback(func, thisArg, argCount) {
if (typeof thisArg === 'undefined') {
return func;
}
switch (argCount) {
case 0:
return function () {
return func.call(thisArg);
};
case 1:
return function (arg) {
return func.call(thisArg, arg);
};
case 2:
return function (value, index) {
return func.call(thisArg, value, index);
};
case 3:
return function (value, index, collection) {
return func.call(thisArg, value, index, collection);
};
}
return function () {
return func.apply(thisArg, arguments);
};
};
/***/ },
/* 45 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var Scheduler = __webpack_require__(21);
var inherits = __webpack_require__(6);
function scheduleRecursive(state, recurse) {
if (state.i < state.len) {
state.o.onNext(state.args[state.i++]);
recurse(state);
} else {
state.o.onCompleted();
}
}
function FromArrayObservable(args, scheduler) {
this._args = args;
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(FromArrayObservable, ObservableBase);
FromArrayObservable.prototype.subscribeCore = function (o) {
var state = {
i: 0,
args: this._args,
len: this._args.length,
o: o
};
return this._scheduler.scheduleRecursive(state, scheduleRecursive);
};
module.exports = function fromArray(array, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new FromArrayObservable(array, scheduler);
};
/***/ },
/* 46 */
/***/ function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
var ObservableBase = __webpack_require__(34);
var fromEventPattern = __webpack_require__(47);
var publish = __webpack_require__(48);
var CompositeDisposable = __webpack_require__(22);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function isNodeList(el) {
if (global.StaticNodeList) {
// IE8 Specific
// instanceof is slower than Object#toString, but Object#toString will not work as intended in IE8
return el instanceof global.StaticNodeList || el instanceof global.NodeList;
} else {
return Object.prototype.toString.call(el) === '[object NodeList]';
}
}
function ListenDisposable(e, n, fn) {
this._e = e;
this._n = n;
this._fn = fn;
this._e.addEventListener(this._n, this._fn, false);
this.isDisposed = false;
}
ListenDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
this._e.removeEventListener(this._n, this._fn, false);
this.isDisposed = true;
}
};
function createEventListener(el, eventName, handler) {
var disposables = new CompositeDisposable();
// Asume NodeList or HTMLCollection
var elemToString = Object.prototype.toString.call(el);
if (isNodeList(el) || elemToString === '[object HTMLCollection]') {
for (var i = 0, len = el.length; i < len; i++) {
disposables.add(createEventListener(el.item(i), eventName, handler));
}
} else if (el) {
disposables.add(new ListenDisposable(el, eventName, handler));
}
return disposables;
}
/**
* Configuration option to determine whether to use native events only
*/
global.Rx || (global.Rx = {});
global.Rx.config || (global.Rx.config = {});
global.Rx.config.useNativeEvents = false;
function EventObservable(el, name, fn) {
this._el = el;
this._n = name;
this._fn = fn;
ObservableBase.call(this);
}
inherits(EventObservable, ObservableBase);
function createHandler(o, fn) {
return function handler() {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) {
return o.onError(results.e);
}
}
o.onNext(results);
};
}
EventObservable.prototype.subscribeCore = function (o) {
return createEventListener(this._el, this._n, createHandler(o, this._fn));
};
/**
* Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList.
* @param {Object} element The DOMElement or NodeList to attach a listener.
* @param {String} eventName The event name to attach the observable sequence.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence of events from the specified element and the specified event.
*/
module.exports = function fromEvent(element, eventName, selector) {
// Node.js specific
if (element.addListener) {
return fromEventPattern(function (h) {
element.addListener(eventName, h);
}, function (h) {
element.removeListener(eventName, h);
}, selector);
}
// Use only if non-native events are allowed
if (!global.Rx.config.useNativeEvents) {
// Handles jq, Angular.js, Zepto, Marionette, Ember.js
if (typeof element.on === 'function' && typeof element.off === 'function') {
return fromEventPattern(function (h) {
element.on(eventName, h);
}, function (h) {
element.off(eventName, h);
}, selector);
}
}
return publish(new EventObservable(element, eventName, selector)).refCount();
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ },
/* 47 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var publish = __webpack_require__(48);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function EventPatternDisposable(del, fn, ret) {
this._del = del;
this._fn = fn;
this._ret = ret;
this.isDisposed = false;
}
EventPatternDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
isFunction(this._del) && this._del(this._fn, this._ret);
this.isDisposed = true;
}
};
function EventPatternObservable(add, del, fn) {
this._add = add;
this._del = del;
this._fn = fn;
ObservableBase.call(this);
}
inherits(EventPatternObservable, ObservableBase);
function createHandler(o, fn) {
return function handler() {
var results = arguments[0];
if (isFunction(fn)) {
results = tryCatch(fn).apply(null, arguments);
if (results === errorObj) {
return o.onError(results.e);
}
}
o.onNext(results);
};
}
EventPatternObservable.prototype.subscribeCore = function (o) {
var fn = createHandler(o, this._fn);
var returnValue = this._add(fn);
return new EventPatternDisposable(this._del, fn, returnValue);
};
/**
* Creates an observable sequence from an event emitter via an addHandler/removeHandler pair.
* @param {Function} addHandler The function to add a handler to the emitter.
* @param {Function} [removeHandler] The optional function to remove a handler from an emitter.
* @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next.
* @returns {Observable} An observable sequence which wraps an event from an event emitter
*/
module.exports = function fromEventPattern(addHandler, removeHandler, selector) {
return publish(new EventPatternObservable(addHandler, removeHandler, selector)).refCount();
};
/***/ },
/* 48 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Subject = __webpack_require__(49);
var multicast = __webpack_require__(50);
var isFunction = __webpack_require__(9);
/**
* Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence.
* This operator is a specialization of Multicast using a regular Subject.
* @param {Function} [selector] Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all notifications of the source from the time of the subscription on.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
module.exports = function publish(source, fn) {
return fn && isFunction(fn) ? multicast(source, function () {
return new Subject();
}, fn) : multicast(source, new Subject());
};
/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(12);
var Observable = __webpack_require__(8);
var Observer = __webpack_require__(1);
var InnerSubscription = __webpack_require__(13);
var addProperties = __webpack_require__(14);
var cloneArray = __webpack_require__(15);
var inherits = __webpack_require__(6);
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed observers.
*/
function Subject() {
Observable.call(this);
this.isDisposed = false;
this.isStopped = false;
this.observers = [];
this.hasError = false;
}
inherits(Subject, Observable);
addProperties(Subject.prototype, Observer.prototype, {
_subscribe: function (o) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
return Disposable.empty;
}
o.onCompleted();
return Disposable.empty;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () {
Disposable.checkDisposed(this);
return this.observers.length > 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.isStopped = true;
this.error = error;
this.hasError = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
Subject.addToObject = function (operators) {
Object.keys(operators).forEach(function (operator) {
Subject[operator] = operators[operator];
});
};
Subject.addToPrototype = function (operators) {
Object.keys(operators).forEach(function (operator) {
Subject.prototype[operator] = function () {
var args = [this];
args.push.apply(args, arguments);
return operators[operator].apply(null, args);
};
});
};
module.exports = Subject;
/***/ },
/* 50 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var ConnectableObservable = __webpack_require__(51);
var BinaryDisposable = __webpack_require__(30);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
function MulticastObservable(source, fn1, fn2) {
this.source = source;
this._fn1 = fn1;
this._fn2 = fn2;
ObservableBase.call(this);
}
inherits(MulticastObservable, ObservableBase);
MulticastObservable.prototype.subscribeCore = function (o) {
var connectable = this.source.multicast(this._fn1());
return new BinaryDisposable(this._fn2(connectable).subscribe(o), connectable.connect());
};
/**
* Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. Each
* subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's
* invocation. For specializations with fixed subject types, see Publish, PublishLast, and Replay.
* @param {Function|Subject} subjectOrSubjectSelector
* Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function.
* Or:
* Subject to push source elements into.
*
* @param {Function} [selector] Optional selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. Specified only if 0;
}
function shiftEach(x) {
return x.shift();
}
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
ZipObserver.prototype.next = function (x) {
this._q[this._i].push(x);
if (this._q.every(notEmpty)) {
var queuedValues = this._q.map(shiftEach);
var res = tryCatch(this._p._cb).apply(null, queuedValues);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onNext(res);
} else if (this._d.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
ZipObserver.prototype.error = function (e) {
this._o.onError(e);
};
ZipObserver.prototype.completed = function () {
this._d[this._i] = true;
this._d.every(identity) && this._o.onCompleted();
};
function ZipObservable(s, cb) {
this._s = s;
this._cb = cb;
ObservableBase.call(this);
}
inherits(ZipObservable, ObservableBase);
ZipObservable.prototype.subscribeCore = function (observer) {
var n = this._s.length,
subscriptions = new Array(n),
done = initializeArray(n, falseFactory),
q = initializeArray(n, emptyArrayFactory);
for (var i = 0; i < n; i++) {
var source = this._s[i],
sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = fromPromise(source));
sad.setDisposable(source.subscribe(new ZipObserver(observer, i, this, q, done)));
}
return new NAryDisposable(subscriptions);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index.
* The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the args.
* @returns {Observable} An observable sequence containing the result of combining elements of the args using the specified result selector function.
*/
module.exports = function zip() {
if (arguments.length === 0) {
throw new Error('invalid arguments');
}
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
return new ZipObservable(args, resultSelector);
};
/***/ },
/* 62 */
/***/ function(module, exports) {
'use strict';
module.exports = function identity(x) {
return x;
};
/***/ },
/* 63 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var SingleAssignmentDisposable = __webpack_require__(19);
var NAryDisposable = __webpack_require__(35);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var identity = __webpack_require__(62);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function falseFactory() {
return false;
}
function initializeArray(n, fn) {
var results = new Array(n);
for (var i = 0; i < n; i++) {
results[i] = fn(i);
}
return results;
}
function argumentsToArray() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
return args;
}
function CombineLatestObserver(o, i, cb, state) {
this._o = o;
this._i = i;
this._cb = cb;
this._state = state;
AbstractObserver.call(this);
}
inherits(CombineLatestObserver, AbstractObserver);
function notTheSame(i) {
return function (x, j) {
return j !== i;
};
}
CombineLatestObserver.prototype.next = function (x) {
this._state.values[this._i] = x;
this._state.hasValue[this._i] = true;
if (this._state.hasValueAll || (this._state.hasValueAll = this._state.hasValue.every(identity))) {
var res = tryCatch(this._cb).apply(null, this._state.values);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onNext(res);
} else if (this._state.isDone.filter(notTheSame(this._i)).every(identity)) {
this._o.onCompleted();
}
};
CombineLatestObserver.prototype.error = function (e) {
this._o.onError(e);
};
CombineLatestObserver.prototype.completed = function () {
this._state.isDone[this._i] = true;
this._state.isDone.every(identity) && this._o.onCompleted();
};
function CombineLatestObservable(params, cb) {
this._params = params;
this._cb = cb;
ObservableBase.call(this);
}
inherits(CombineLatestObservable, ObservableBase);
CombineLatestObservable.prototype.subscribeCore = function (observer) {
var len = this._params.length,
subscriptions = new Array(len);
var state = {
hasValue: initializeArray(len, falseFactory),
hasValueAll: false,
isDone: initializeArray(len, falseFactory),
values: new Array(len)
};
for (var i = 0; i < len; i++) {
var source = this._params[i],
sad = new SingleAssignmentDisposable();
subscriptions[i] = sad;
isPromise(source) && (source = fromPromise(source));
sad.setDisposable(source.subscribe(new CombineLatestObserver(observer, i, this._cb, state)));
}
return new NAryDisposable(subscriptions);
};
/**
* Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences or Promises produces an element.
*
* @example
* 1 - obs = Rx.Observable.combineLatest(obs1, obs2, obs3, function (o1, o2, o3) { return o1 + o2 + o3; });
* 2 - obs = Rx.Observable.combineLatest([obs1, obs2, obs3], function (o1, o2, o3) { return o1 + o2 + o3; });
* @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function.
*/
module.exports = function combineLatest() {
var len = arguments.length,
args = new Array(len);
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var resultSelector = isFunction(args[len - 1]) ? args.pop() : argumentsToArray;
return new CombineLatestObservable(args, resultSelector);
};
/***/ },
/* 64 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var mergeConcat = __webpack_require__(65);
module.exports = function concatAll(sources) {
return mergeConcat(sources, 1);
};
/***/ },
/* 65 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var CompositeDisposable = __webpack_require__(22);
var SingleAssignmentDisposable = __webpack_require__(19);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var inherits = __webpack_require__(6);
function InnerObserver(parent, sad) {
this._p = parent;
this._sad = sad;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) {
this._p._o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this._p._o.onError(e);
};
InnerObserver.prototype.completed = function () {
this._p._g.remove(this._sad);
if (this._p._q.length > 0) {
this._p.handleSubscribe(this._p._q.shift());
} else {
this._p._activeCount--;
this._p._done && this._p._activeCount === 0 && this._p._o.onCompleted();
}
};
function MergeObserver(o, max, g) {
this._o = o;
this._max = max;
this._g = g;
this._done = false;
this._q = [];
this._activeCount = 0;
AbstractObserver.call(this);
}
inherits(MergeObserver, AbstractObserver);
MergeObserver.prototype.handleSubscribe = function (xs) {
var sad = new SingleAssignmentDisposable();
this._g.add(sad);
isPromise(xs) && (xs = fromPromise(xs));
sad.setDisposable(xs.subscribe(new InnerObserver(this, sad)));
};
MergeObserver.prototype.next = function (innerSource) {
if (this._activeCount < this._max) {
this._activeCount++;
this.handleSubscribe(innerSource);
} else {
this._q.push(innerSource);
}
};
MergeObserver.prototype.error = function (e) {
this._o.onError(e);
};
MergeObserver.prototype.completed = function () {
this._done = true;this._activeCount === 0 && this._o.onCompleted();
};
function MergeObservable(source, maxConcurrent) {
this.source = source;
this._maxConcurrent = maxConcurrent;
ObservableBase.call(this);
}
inherits(MergeObservable, ObservableBase);
MergeObservable.prototype.subscribeCore = function (observer) {
var g = new CompositeDisposable();
g.add(this.source.subscribe(new MergeObserver(observer, this._maxConcurrent, g)));
return g;
};
/**
* Merges an observable sequence of observable sequences into an observable sequence, limiting the number of concurrent subscriptions to inner sequences.
* Or merges two observable sequences into a single observable sequence.
* @param {Mixed} [maxConcurrentOrOther] Maximum number of inner observable sequences being subscribed to concurrently or the second observable sequence.
* @returns {Observable} The observable sequence that merges the elements of the inner sequences.
*/
module.exports = function mergeConcat(source, maxConcurrent) {
return new MergeObservable(source, maxConcurrent);
};
/***/ },
/* 66 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var Scheduler = __webpack_require__(21);
var BinaryDisposable = __webpack_require__(30);
var SerialDisposable = __webpack_require__(36);
var SingleAssignmentDisposable = __webpack_require__(19);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var isFunction = __webpack_require__(9);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
var inherits = __webpack_require__(6);
function DebounceObserver(o, dt, scheduler, cancelable) {
this._o = o;
this._d = dt;
this._scheduler = scheduler;
this._c = cancelable;
this._v = null;
this._hv = false;
this._id = 0;
AbstractObserver.call(this);
}
inherits(DebounceObserver, AbstractObserver);
DebounceObserver.prototype.next = function (x) {
this._hv = true;
this._v = x;
var currentId = ++this._id,
d = new SingleAssignmentDisposable();
this._c.setDisposable(d);
d.setDisposable(this._scheduler.scheduleFuture(this, this._d, function (_, self) {
self._hv && self._id === currentId && self._o.onNext(x);
self._hv = false;
}));
};
DebounceObserver.prototype.error = function (e) {
this._c.dispose();
this._o.onError(e);
this._hv = false;
this._id++;
};
DebounceObserver.prototype.completed = function () {
this._c.dispose();
this._hv && this._o.onNext(this._v);
this._o.onCompleted();
this._hv = false;
this._id++;
};
function DebounceObservable(source, dt, s) {
Scheduler.isScheduler(s) || (s = Scheduler.async);
this.source = source;
this._dt = dt;
this._s = s;
ObservableBase.call(this);
}
inherits(DebounceObservable, ObservableBase);
DebounceObservable.prototype.subscribeCore = function (o) {
var cancelable = new SerialDisposable();
return new BinaryDisposable(this.source.subscribe(new DebounceObserver(o, this._dt, this._s, cancelable)), cancelable);
};
function DebounceSelectorObserver(s) {
this._s = s;
AbstractObserver.call(this);
}
inherits(DebounceSelectorObserver, AbstractObserver);
DebounceSelectorObserver.prototype.next = function (x) {
var throttle = tryCatch(this._s.fn)(x);
if (throttle === errorObj) {
return this._s.o.onError(throttle.e);
}
isPromise(throttle) && (throttle = fromPromise(throttle));
this._s.hasValue = true;
this._s.value = x;
this._s.id++;
var currentId = this._s.id,
d = new SingleAssignmentDisposable();
this._s.cancelable.setDisposable(d);
var self = this;
d.setDisposable(throttle.subscribe(function () {
self._s.hasValue && self._s.id === currentId && self._s.o.onNext(self._s.value);
self._s.hasValue = false;
d.dispose();
}, function (e) {
self._s.o.onError(e);
}, function () {
self._s.hasValue && self._s.id === currentId && self._s.o.onNext(self._s.value);
self._s.hasValue = false;
d.dispose();
}));
};
DebounceSelectorObserver.prototype.error = function (e) {
this._s.cancelable.dispose();
this._s.o.onError(e);
this._s.hasValue = false;
this._s.id++;
};
DebounceSelectorObserver.prototype.completed = function () {
this._s.cancelable.dispose();
this._s.hasValue && this._s.o.onNext(this._s.value);
this._s.o.onCompleted();
this._s.hasValue = false;
this._s.id++;
};
function DebounceSelectorObservable(source, fn) {
this.source = source;
this._fn = fn;
ObservableBase.call(this);
}
inherits(DebounceSelectorObservable, ObservableBase);
DebounceSelectorObservable.prototype.subscribeCore = function (o) {
var state = {
value: null,
hasValue: false,
cancelable: new SerialDisposable(),
id: 0,
o: o,
fn: this._fn
};
return new BinaryDisposable(state.cancelable, this.source.subscribe(new DebounceSelectorObserver(state)));
};
module.exports = function debounce() {
var source = arguments[0];
if (isFunction(arguments[1])) {
return new DebounceSelectorObservable(source, arguments[1]);
} else if (typeof arguments[1] === 'number') {
return new DebounceObservable(source, arguments[1], arguments[2]);
} else {
throw new Error('Invalid arguments');
}
};
/***/ },
/* 67 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var isFunction = __webpack_require__(9);
var isEqual = __webpack_require__(68);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function DistinctUntilChangedObserver(o, fn, cmp) {
this._o = o;
this._fn = fn;
this._cmp = cmp;
this._hk = false;
this._k = null;
AbstractObserver.call(this);
}
inherits(DistinctUntilChangedObserver, AbstractObserver);
DistinctUntilChangedObserver.prototype.next = function (x) {
var key = x,
comparerEquals;
if (isFunction(this._fn)) {
key = tryCatch(this._fn)(x);
if (key === errorObj) {
return this._o.onError(key.e);
}
}
if (this._hk) {
comparerEquals = tryCatch(this._cmp)(this._k, key);
if (comparerEquals === errorObj) {
return this._o.onError(comparerEquals.e);
}
}
if (!this._hk || !comparerEquals) {
this._hk = true;
this._k = key;
this._o.onNext(x);
}
};
DistinctUntilChangedObserver.prototype.error = function (e) {
this._o.onError(e);
};
DistinctUntilChangedObserver.prototype.completed = function () {
this._o.onCompleted();
};
function DistinctUntilChangedObservable(source, fn, cmp) {
this.source = source;
this._fn = fn;
this._cmp = cmp;
ObservableBase.call(this);
}
inherits(DistinctUntilChangedObservable, ObservableBase);
DistinctUntilChangedObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new DistinctUntilChangedObserver(o, this._fn, this._cmp));
};
/**
* Returns an observable sequence that contains only distinct contiguous elements according to the keyFn and the comparer.
* @param {Function} [keyFn] A function to compute the comparison key for each element. If not provided, it projects the value.
* @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function.
* @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence.
*/
module.exports = function distinctUntilChanged(source, keyFn, comparer) {
comparer || (comparer = isEqual);
return new DistinctUntilChangedObservable(source, keyFn, comparer);
};
/***/ },
/* 68 */
/***/ function(module, exports) {
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
var objectProto = Object.prototype,
hasOwnProperty = objectProto.hasOwnProperty,
objToString = objectProto.toString,
MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var keys = Object.keys || function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString'),
dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [],
prop,
i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}();
function equalObjects(object, other, equalFunc, isLoose, stackA, stackB) {
var objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
othLength = othProps.length;
if (objLength !== othLength && !isLoose) {
return false;
}
var index = objLength,
key;
while (index--) {
key = objProps[index];
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
return false;
}
}
var skipCtor = isLoose;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key],
result;
if (!(result === undefined ? equalFunc(objValue, othValue, isLoose, stackA, stackB) : result)) {
return false;
}
skipCtor || (skipCtor = key === 'constructor');
}
if (!skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
if (objCtor !== othCtor && 'constructor' in object && 'constructor' in other && !(typeof objCtor === 'function' && objCtor instanceof objCtor && typeof othCtor === 'function' && othCtor instanceof othCtor)) {
return false;
}
}
return true;
}
function equalByTag(object, other, tag) {
switch (tag) {
case boolTag:
case dateTag:
return +object === +other;
case errorTag:
return object.name === other.name && object.message === other.message;
case numberTag:
return object !== +object ? other !== +other : object === +other;
case regexpTag:
case stringTag:
return object === other + '';
}
return false;
}
function isObject(value) {
var type = typeof value;
return !!value && (type === 'object' || type === 'function');
}
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
function isLength(value) {
return typeof value === 'number' && value > -1 && value % 1 === 0 && value <= MAX_SAFE_INTEGER;
}
var isHostObject = function () {
try {
Object({ 'toString': 0 } + '');
} catch (e) {
return function () {
return false;
};
}
return function (value) {
return typeof value.toString !== 'function' && typeof (value + '') === 'string';
};
}();
function isTypedArray(value) {
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}
var isArray = Array.isArray || function (value) {
return isObjectLike(value) && isLength(value.length) && objToString.call(value) === arrayTag;
};
function arraySome(array, predicate) {
var index = -1,
length = array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
function equalArrays(array, other, equalFunc, isLoose, stackA, stackB) {
var index = -1,
arrLength = array.length,
othLength = other.length;
if (arrLength !== othLength && !(isLoose && othLength > arrLength)) {
return false;
}
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index],
result;
if (result !== undefined) {
if (result) {
continue;
}
return false;
}
// Recursively compare arrays (susceptible to call stack limits).
if (isLoose) {
if (!arraySome(other, function (othValue) {
return arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB);
})) {
return false;
}
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, isLoose, stackA, stackB))) {
return false;
}
}
return true;
}
function baseIsEqualDeep(object, other, equalFunc, isLoose, stackA, stackB) {
var objIsArr = isArray(object),
othIsArr = isArray(other),
objTag = arrayTag,
othTag = arrayTag;
if (!objIsArr) {
objTag = objToString.call(object);
if (objTag === argsTag) {
objTag = objectTag;
} else if (objTag !== objectTag) {
objIsArr = isTypedArray(object);
}
}
if (!othIsArr) {
othTag = objToString.call(other);
if (othTag === argsTag) {
othTag = objectTag;
} else if (othTag !== objectTag) {
othIsArr = isTypedArray(other);
}
}
var objIsObj = objTag === objectTag && !isHostObject(object),
othIsObj = othTag === objectTag && !isHostObject(other),
isSameTag = objTag === othTag;
if (isSameTag && !(objIsArr || objIsObj)) {
return equalByTag(object, other, objTag);
}
if (!isLoose) {
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, isLoose, stackA, stackB);
}
}
if (!isSameTag) {
return false;
}
// Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO.
stackA || (stackA = []);
stackB || (stackB = []);
var length = stackA.length;
while (length--) {
if (stackA[length] === object) {
return stackB[length] === other;
}
}
// Add `object` and `other` to the stack of traversed objects.
stackA.push(object);
stackB.push(other);
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, isLoose, stackA, stackB);
stackA.pop();
stackB.pop();
return result;
}
function baseIsEqual(value, other, isLoose, stackA, stackB) {
if (value === other) {
return true;
}
if (value == null || other == null || !isObject(value) && !isObjectLike(other)) {
return value !== value && other !== other;
}
return baseIsEqualDeep(value, other, baseIsEqual, isLoose, stackA, stackB);
}
module.exports = function (value, other) {
return baseIsEqual(value, other);
};
/***/ },
/* 69 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var create = __webpack_require__(2);
var isFunction = __webpack_require__(9);
var noop = __webpack_require__(3);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function TapObserver(o, p) {
this._o = o;
this._t = !p._oN || isFunction(p._oN) ? create(p._oN || noop, p._oE || noop, p._oC || noop) : p._oN;
this.isStopped = false;
AbstractObserver.call(this);
}
inherits(TapObserver, AbstractObserver);
TapObserver.prototype.next = function (x) {
var res = tryCatch(this._t.onNext).call(this._t, x);
if (res === errorObj) {
this._o.onError(res.e);
}
this._o.onNext(x);
};
TapObserver.prototype.error = function (e) {
var res = tryCatch(this._t.onError).call(this._t, e);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onError(e);
};
TapObserver.prototype.completed = function () {
var res = tryCatch(this._t.onCompleted).call(this._t);
if (res === errorObj) {
return this._o.onError(res.e);
}
this._o.onCompleted();
};
function TapObservable(source, observerOrOnNext, onError, onCompleted) {
this.source = source;
this._oN = observerOrOnNext;
this._oE = onError;
this._oC = onCompleted;
ObservableBase.call(this);
}
inherits(TapObservable, ObservableBase);
TapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TapObserver(o, this));
};
/**
* Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence.
* This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline.
* @param {Function | Observer} observerOrOnNext Action to invoke for each element in the observable sequence or an o.
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function.
* @returns {Observable} The source sequence with the side-effecting behavior applied.
*/
module.exports = function tap(source, observerOrOnNext, onError, onCompleted) {
return new TapObservable(source, observerOrOnNext, onError, onCompleted);
};
/***/ },
/* 70 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var bindCallback = __webpack_require__(44);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function FilterObserver(o, predicate, source) {
this._o = o;
this._fn = predicate;
this.source = source;
this._i = 0;
AbstractObserver.call(this);
}
inherits(FilterObserver, AbstractObserver);
FilterObserver.prototype.next = function (x) {
var shouldYield = tryCatch(this._fn)(x, this._i++, this.source);
if (shouldYield === errorObj) {
return this._o.onError(shouldYield.e);
}
shouldYield && this._o.onNext(x);
};
FilterObserver.prototype.error = function (e) {
this._o.onError(e);
};
FilterObserver.prototype.completed = function () {
this._o.onCompleted();
};
function FilterObservable(source, predicate, thisArg) {
this.source = source;
this._fn = bindCallback(predicate, thisArg, 3);
ObservableBase.call(this);
}
inherits(FilterObservable, ObservableBase);
FilterObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FilterObserver(o, this._fn, this));
};
function innerPredicate(fn, self) {
return function (x, i, o) {
return self._fn(x, i, o) && fn.call(this, x, i, o);
};
}
FilterObservable.prototype.internalFilter = function (fn, thisArg) {
return new FilterObservable(this.source, innerPredicate(fn, this), thisArg);
};
/**
* Filters the elements of an observable sequence based on a predicate by incorporating the element's index.
* @param {Function} predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element.
* @param {Any} [thisArg] Object to use as this when executing callback.
* @returns {Observable} An observable sequence that contains elements from the input sequence that satisfy the condition.
*/
module.exports = function filter(source, predicate, thisArg) {
return source instanceof FilterObservable ? source.internalFilter(predicate, thisArg) : new FilterObservable(source, predicate, thisArg);
};
/***/ },
/* 71 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var inherits = __webpack_require__(6);
var bindCallback = __webpack_require__(44);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function FinallyDisposable(s, fn) {
this.isDisposed = false;
this._s = s;
this._fn = fn;
}
FinallyDisposable.prototype.dispose = function () {
if (!this.isDisposed) {
var res = tryCatch(this._s.dispose).call(this._s);
this._fn();
res === errorObj && thrower(res.e);
}
};
function FinallyObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 0);
ObservableBase.call(this);
}
inherits(FinallyObservable, ObservableBase);
FinallyObservable.prototype.subscribeCore = function (o) {
var d = tryCatch(this.source.subscribe).call(this.source, o);
if (d === errorObj) {
this._fn();
thrower(d.e);
}
return new FinallyDisposable(d, this._fn);
};
/**
* Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
* @param {Function} finallyAction Action to invoke after the source observable sequence terminates.
* @returns {Observable} Source sequence with the action-invoking termination behavior applied.
*/
module.exports = function finally_(source, action, thisArg) {
return new FinallyObservable(source, action, thisArg);
};
/***/ },
/* 72 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var FlatMapObservable = __webpack_require__(73);
var mergeAll = __webpack_require__(55);
module.exports = function flatMap(source, selector, resultSelector, thisArg) {
var obs = new FlatMapObservable(source, selector, resultSelector, thisArg);
return mergeAll(obs);
};
/***/ },
/* 73 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var ObservableBase = __webpack_require__(34);
var observableFrom = __webpack_require__(42);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var isArrayLike = __webpack_require__(74);
var isIterable = __webpack_require__(75);
var bindCallback = __webpack_require__(44);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function FlatMapObserver(o, selector, resultSelector, source) {
this.i = 0;
this._fn = selector;
this._resFn = resultSelector;
this.source = source;
this._o = o;
AbstractObserver.call(this);
}
inherits(FlatMapObserver, AbstractObserver);
FlatMapObserver.prototype._wrapResult = function (result, x, i) {
return isFunction(this._resFn) ? result.map(function (y, i2) {
return this._resFn(x, y, i, i2);
}, this) : result;
};
FlatMapObserver.prototype.next = function (x) {
var i = this.i++;
var result = tryCatch(this._fn)(x, i, this.source);
if (result === errorObj) {
return this._o.onError(result.e);
}
isPromise(result) && (result = fromPromise(result));
(isArrayLike(result) || isIterable(result)) && (result = observableFrom(result));
this._o.onNext(this._wrapResult(result, x, i));
};
FlatMapObserver.prototype.error = function (e) {
this._o.onError(e);
};
FlatMapObserver.prototype.completed = function () {
this._o.onCompleted();
};
function FlatMapObservable(source, fn, resultFn, thisArg) {
this._resFn = isFunction(resultFn) ? resultFn : null;
this._fn = bindCallback(isFunction(fn) ? fn : function () {
return fn;
}, thisArg, 3);
this.source = source;
ObservableBase.call(this);
}
inherits(FlatMapObservable, ObservableBase);
FlatMapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new FlatMapObserver(o, this._fn, this._resFn, this));
};
module.exports = FlatMapObservable;
/***/ },
/* 74 */
/***/ function(module, exports) {
'use strict';
module.exports = function isArrayLike(o) {
return o && o.length !== undefined;
};
/***/ },
/* 75 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var $iterator$ = __webpack_require__(43);
module.exports = function isIterable(o) {
return o && o[$iterator$] !== undefined;
};
/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var FlatMapObservable = __webpack_require__(73);
var switchLatest = __webpack_require__(77);
module.exports = function flatMapLatest(source, selector, resultSelector, thisArg) {
return switchLatest(new FlatMapObservable(source, selector, resultSelector, thisArg));
};
/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var BinaryDisposable = __webpack_require__(30);
var SerialDisposable = __webpack_require__(36);
var SingleAssignmentDisposable = __webpack_require__(19);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var inherits = __webpack_require__(6);
function InnerObserver(p, id) {
this._p = p;
this._id = id;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) {
this._p._latest === this._id && this._p._o.onNext(x);
};
InnerObserver.prototype.error = function (e) {
this._p._latest === this._id && this._p._o.onError(e);
};
InnerObserver.prototype.completed = function () {
if (this._p._latest === this._id) {
this._p._hasLatest = false;
this._p._stopped && this._p._o.onCompleted();
}
};
function SwitchObserver(o, inner) {
this._o = o;
this._inner = inner;
this._stopped = false;
this._latest = 0;
this._hasLatest = false;
AbstractObserver.call(this);
}
inherits(SwitchObserver, AbstractObserver);
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(),
id = ++this._latest;
this._hasLatest = true;
this._inner.setDisposable(d);
isPromise(innerSource) && (innerSource = fromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) {
this._o.onError(e);
};
SwitchObserver.prototype.completed = function () {
this._stopped = true;!this._hasLatest && this._o.onCompleted();
};
function SwitchObservable(source) {
this.source = source;
ObservableBase.call(this);
}
inherits(SwitchObservable, ObservableBase);
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(),
s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
module.exports = function switch_(source) {
return new SwitchObservable(source);
};
/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var bindCallback = __webpack_require__(44);
var isFunction = __webpack_require__(9);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function MapObserver(o, selector, source) {
this._o = o;
this._fn = selector;
this._s = source;
this._i = 0;
AbstractObserver.call(this);
}
inherits(MapObserver, AbstractObserver);
MapObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) {
return this._o.onError(result.e);
}
this._o.onNext(result);
};
MapObserver.prototype.error = function (e) {
this._o.onError(e);
};
MapObserver.prototype.completed = function () {
this._o.onCompleted();
};
function MapObservable(source, fn, thisArg) {
this.source = source;
this._fn = bindCallback(fn, thisArg, 3);
ObservableBase.call(this);
}
inherits(MapObservable, ObservableBase);
function innerMap(fn, self) {
return function (x, i, o) {
return fn.call(this, self._fn(x, i, o), i, o);
};
}
MapObservable.prototype.internalMap = function (fn, thisArg) {
return new MapObservable(this.source, innerMap(fn, this), thisArg);
};
MapObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new MapObserver(o, this._fn, this));
};
module.exports = function map(source, fn, thisArg) {
var thisFn = isFunction(fn) ? fn : function () {
return fn;
};
return source instanceof MapObservable ? source.internalMap(thisFn, thisArg) : new MapObservable(source, thisFn, thisArg);
};
/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var map = __webpack_require__(78);
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
module.exports = function pluck() {
var len = arguments.length,
args = new Array(len);
if (len === 0) {
throw new Error('List of properties cannot be empty.');
}
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var pluckedArgs = args.slice(1);
return map(args[0], plucker(pluckedArgs, pluckedArgs.length));
};
/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AsyncSubject = __webpack_require__(11);
var multicast = __webpack_require__(50);
var isFunction = __webpack_require__(9);
module.exports = function publishLast(source, selector) {
return isFunction(selector) ? multicast(source, function () {
return new AsyncSubject();
}, selector) : multicast(source, new AsyncSubject());
};
/***/ },
/* 81 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var multicast = __webpack_require__(50);
var BehaviorSubject = __webpack_require__(82);
function createBehaviorSubject(initialValue) {
return function fn() {
return new BehaviorSubject(initialValue);
};
}
module.exports = function publishValue() {
var source = arguments[0];
if (arguments.length === 3) {
return multicast(source, createBehaviorSubject(arguments[2]), arguments[1]);
} else if (arguments.length === 2) {
return multicast(source, new BehaviorSubject(arguments[1]));
} else {
throw new Error('Invalid arguments');
}
};
/***/ },
/* 82 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Observable = __webpack_require__(8);
var Observer = __webpack_require__(1);
var Disposable = __webpack_require__(12);
var InnerSubscription = __webpack_require__(13);
var addProperties = __webpack_require__(14);
var cloneArray = __webpack_require__(15);
var thrower = __webpack_require__(20).thrower;
var inherits = __webpack_require__(6);
/**
* Represents a value that changes over time.
* Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
*/
function BehaviorSubject(value) {
this.value = value;
this.observers = [];
this.isDisposed = false;
this.isStopped = false;
this.hasError = false;
Observable.call(this);
}
inherits(BehaviorSubject, Observable);
addProperties(BehaviorSubject.prototype, Observer.prototype, {
_subscribe: function (o) {
Disposable.checkDisposed(this);
if (!this.isStopped) {
this.observers.push(o);
o.onNext(this.value);
return new InnerSubscription(this, o);
}
if (this.hasError) {
o.onError(this.error);
} else {
o.onCompleted();
}
return Disposable.empty;
},
/**
* Gets the current value or throws an exception.
* Value is frozen after onCompleted is called.
* After onError is called always throws the specified exception.
* An exception is always thrown after dispose is called.
* @returns {Mixed} The initial value passed to the constructor until onNext is called; after which, the last value passed to onNext.
*/
getValue: function () {
Disposable.checkDisposed(this);
if (this.hasError) {
thrower(this.error);
}
return this.value;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () {
Disposable.checkDisposed(this);
return this.observers.length > 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.isStopped = true;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onCompleted();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.isStopped = true;
this.hasError = true;
this.error = error;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onError(error);
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.value = value;
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
os[i].onNext(value);
}
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
this.value = null;
this.error = null;
}
});
module.exports = BehaviorSubject;
/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var multicast = __webpack_require__(50);
var ReplaySubject = __webpack_require__(84);
var isFunction = __webpack_require__(9);
module.exports = function replay(source, selector, bufferSize, windowSize, scheduler) {
return isFunction(selector) ? multicast(source, function () {
return new ReplaySubject(bufferSize, windowSize, scheduler);
}, selector) : multicast(source, new ReplaySubject(bufferSize, windowSize, scheduler));
};
/***/ },
/* 84 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Disposable = __webpack_require__(12);
var Observable = __webpack_require__(8);
var Observer = __webpack_require__(1);
var ScheduledObserver = __webpack_require__(85);
var Scheduler = __webpack_require__(21);
var addProperties = __webpack_require__(14);
var cloneArray = __webpack_require__(15);
var inherits = __webpack_require__(6);
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
function createRemovableDisposable(subject, observer) {
return Disposable.create(function () {
observer.dispose();
!subject.isDisposed && subject.observers.splice(subject.observers.indexOf(observer), 1);
});
}
/**
* Represents an object that is both an observable sequence as well as an observer.
* Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
*
* Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler.
* @param {Number} [bufferSize] Maximum element count of the replay buffer.
* @param {Number} [windowSize] Maximum time length of the replay buffer.
* @param {Scheduler} [scheduler] Scheduler the observers are invoked on.
*/
function ReplaySubject(bufferSize, windowSize, scheduler) {
this.bufferSize = bufferSize == null ? MAX_SAFE_INTEGER : bufferSize;
this.windowSize = windowSize == null ? MAX_SAFE_INTEGER : windowSize;
this.scheduler = scheduler || Scheduler.queue;
this.q = [];
this.observers = [];
this.isStopped = false;
this.isDisposed = false;
this.hasError = false;
this.error = null;
Observable.call(this);
}
inherits(ReplaySubject, Observable);
addProperties(ReplaySubject.prototype, Observer.prototype, {
_subscribe: function (o) {
Disposable.checkDisposed(this);
var so = new ScheduledObserver(this.scheduler, o),
subscription = createRemovableDisposable(this, so);
this._trim(this.scheduler.now());
this.observers.push(so);
for (var i = 0, len = this.q.length; i < len; i++) {
so.onNext(this.q[i].value);
}
if (this.hasError) {
so.onError(this.error);
} else if (this.isStopped) {
so.onCompleted();
}
so.ensureActive();
return subscription;
},
/**
* Indicates whether the subject has observers subscribed to it.
* @returns {Boolean} Indicates whether the subject has observers subscribed to it.
*/
hasObservers: function () {
Disposable.checkDisposed(this);
return this.observers.length > 0;
},
_trim: function (now) {
while (this.q.length > this.bufferSize) {
this.q.shift();
}
while (this.q.length > 0 && now - this.q[0].interval > this.windowSize) {
this.q.shift();
}
},
/**
* Notifies all subscribed observers about the arrival of the specified element in the sequence.
* @param {Mixed} value The value to send to all observers.
*/
onNext: function (value) {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
var now = this.scheduler.now();
this.q.push({ interval: now, value: value });
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onNext(value);
observer.ensureActive();
}
},
/**
* Notifies all subscribed observers about the exception.
* @param {Mixed} error The exception to send to all observers.
*/
onError: function (error) {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.isStopped = true;
this.error = error;
this.hasError = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onError(error);
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Notifies all subscribed observers about the end of the sequence.
*/
onCompleted: function () {
Disposable.checkDisposed(this);
if (this.isStopped) {
return;
}
this.isStopped = true;
var now = this.scheduler.now();
this._trim(now);
for (var i = 0, os = cloneArray(this.observers), len = os.length; i < len; i++) {
var observer = os[i];
observer.onCompleted();
observer.ensureActive();
}
this.observers.length = 0;
},
/**
* Unsubscribe all observers and release resources.
*/
dispose: function () {
this.isDisposed = true;
this.observers = null;
}
});
module.exports = ReplaySubject;
/***/ },
/* 85 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var SerialDisposable = __webpack_require__(36);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj,
thrower = tryCatchUtils.thrower;
function ScheduledObserver(scheduler, observer) {
AbstractObserver.call(this);
this.scheduler = scheduler;
this.observer = observer;
this.isAcquired = false;
this.hasFaulted = false;
this.queue = [];
this.disposable = new SerialDisposable();
}
inherits(ScheduledObserver, AbstractObserver);
function enqueueNext(observer, x) {
return function () {
observer.onNext(x);
};
}
function enqueueError(observer, e) {
return function () {
observer.onError(e);
};
}
function enqueueCompleted(observer) {
return function () {
observer.onCompleted();
};
}
ScheduledObserver.prototype.next = function (x) {
this.queue.push(enqueueNext(this.observer, x));
};
ScheduledObserver.prototype.error = function (e) {
this.queue.push(enqueueError(this.observer, e));
};
ScheduledObserver.prototype.completed = function () {
this.queue.push(enqueueCompleted(this.observer));
};
function scheduleMethod(state, recurse) {
var work;
if (state.queue.length > 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner && this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
AbstractObserver.prototype.dispose.call(this);
this.disposable.dispose();
};
module.exports = ScheduledObserver;
/***/ },
/* 86 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var inherits = __webpack_require__(6);
var tryCatchUtils = __webpack_require__(20);
var tryCatch = tryCatchUtils.tryCatch,
errorObj = tryCatchUtils.errorObj;
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
AbstractObserver.call(this);
}
inherits(ScanObserver, AbstractObserver);
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) {
return this._o.onError(this._a.e);
}
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) {
this._o.onError(e);
};
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
ObservableBase.call(this);
}
inherits(ScanObservable, ObservableBase);
ScanObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new ScanObserver(o, this));
};
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
module.exports = function scan() {
var source = arguments[0],
hasSeed = false,
seed,
accumulator = arguments[1];
if (arguments.length === 3) {
hasSeed = true;
seed = arguments[2];
}
return new ScanObservable(source, accumulator, hasSeed, seed);
};
/***/ },
/* 87 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var publish = __webpack_require__(48);
module.exports = function share(source) {
return publish(source).refCount();
};
/***/ },
/* 88 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var replay = __webpack_require__(83);
module.exports = function shareReplay(source, bufferSize, windowSize, scheduler) {
return replay(source, null, bufferSize, windowSize, scheduler).refCount();
};
/***/ },
/* 89 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var publishValue = __webpack_require__(81);
module.exports = function shareValue(source, initialValue) {
return publishValue(source, initialValue).refCount();
};
/***/ },
/* 90 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var ObservableBase = __webpack_require__(34);
var errors = __webpack_require__(7);
var inherits = __webpack_require__(6);
function SkipObserver(o, r) {
this._o = o;
this._r = r;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function (e) {
this._o.onError(e);
};
SkipObserver.prototype.completed = function () {
this._o.onCompleted();
};
function SkipObservable(source, count) {
this.source = source;
this._count = count;
ObservableBase.call(this);
}
inherits(SkipObservable, ObservableBase);
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
module.exports = function skip(source, count) {
if (count < 0) {
throw new errors.ArgumentOutOfRangeError();
}
return new SkipObservable(source, count);
};
/***/ },
/* 91 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ObservableBase = __webpack_require__(34);
var AbstractObserver = __webpack_require__(5);
var BinaryDisposable = __webpack_require__(30);
var SingleAssignmentDisposable = __webpack_require__(19);
var fromPromise = __webpack_require__(37);
var isPromise = __webpack_require__(38);
var inherits = __webpack_require__(6);
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
AbstractObserver.call(this);
}
inherits(SkipUntilSourceObserver, AbstractObserver);
SkipUntilSourceObserver.prototype.next = function (x) {
this._p._open && this._o.onNext(x);
};
SkipUntilSourceObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilSourceObserver.prototype.onCompleted = function () {
this._p._open && this._o.onCompleted();
};
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
AbstractObserver.call(this);
}
inherits(SkipUntilOtherObserver, AbstractObserver);
SkipUntilOtherObserver.prototype.next = function () {
this._p._open = true;this._r.dispose();
};
SkipUntilOtherObserver.prototype.error = function (err) {
this._o.onError(err);
};
SkipUntilOtherObserver.prototype.onCompleted = function () {
this._r.dispose();
};
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? fromPromise(other) : other;
this._open = false;
ObservableBase.call(this);
}
inherits(SkipUntilObservable, ObservableBase);
SkipUntilObservable.prototype.subscribeCore = function (o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = fromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
module.exports = function skipUntil(source, other) {
return new SkipUntilObservable(source, other);
};
/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var AbstractObserver = __webpack_require__(5);
var ObservableBase = __webpack_require__(34);
var empty = __webpack_require__(41);
var errors = __webpack_require__(7);
var inherits = __webpack_require__(6);
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) {
this._o.onError(e);
};
TakeObserver.prototype.completed = function () {
this._o.onCompleted();
};
function TakeObservable(source, count) {
this.source = source;
this._count = count;
ObservableBase.call(this);
}
inherits(TakeObservable, ObservableBase);
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) { this._o.onNext(this._q.shift()); }
};
PausableBufferedObserver.prototype.next = function (x) {
if (this._previousShouldFire !== null && x.shouldFire !== this._previousShouldFire) {
this._previousShouldFire = x.shouldFire;
// change in shouldFire
if (x.shouldFire) { this.drainQueue(); }
} else {
this._previousShouldFire = x.shouldFire;
// new data
if (x.shouldFire) {
this._o.onNext(x.data);
} else {
this._q.push(x.data);
}
}
};
PausableBufferedObserver.prototype.error = function (e) {
this.drainQueue();
this._o.onError(e);
};
PausableBufferedObserver.prototype.completed = function () {
this.drainQueue();
this._o.onCompleted();
};
function PausableBufferedObservable(source, pauser) {
this.source = source;
this.controller = new Subject();
this.paused = true;
if (pauser && pauser.subscribe) {
this.pauser = merge(this.controller, pauser);
} else {
this.pauser = this.controller;
}
Observable.call(this);
}
inherits(PausableBufferedObservable, Observable);
function selectorFn(data, shouldFire) {
return { data: data, shouldFire: shouldFire };
}
PausableBufferedObservable.prototype._subscribe = function (o) {
return combineLatestSource(
this.source,
distinctUntilChanged(startWith(this.pauser, !this.paused)),
selectorFn)
.subscribe(new PausableBufferedObserver(o));
};
PausableBufferedObservable.prototype.pause = function () {
this.controller.onNext(false);
this.paused = true;
};
PausableBufferedObservable.prototype.resume = function () {
this.controller.onNext(true);
this.paused = false;
};
module.exports = function pausableBuffered (source, pauser) {
return new PausableBufferedObservable(source, pauser);
};
================================================
FILE: src/modular/observable/pluck.js
================================================
'use strict';
var map = require('./map');
function plucker(args, len) {
return function mapper(x) {
var currentProp = x;
for (var i = 0; i < len; i++) {
var p = currentProp[args[i]];
if (typeof p !== 'undefined') {
currentProp = p;
} else {
return undefined;
}
}
return currentProp;
};
}
/**
* Retrieves the value of a specified nested property from all elements in
* the Observable sequence.
* @param {Arguments} arguments The nested properties to pluck.
* @returns {Observable} Returns a new Observable sequence of property values.
*/
module.exports = function pluck() {
var len = arguments.length, args = new Array(len);
if (len === 0) { throw new Error('List of properties cannot be empty.'); }
for(var i = 0; i < len; i++) { args[i] = arguments[i]; }
var pluckedArgs = args.slice(1);
return map(args[0], plucker(pluckedArgs, pluckedArgs.length));
};
================================================
FILE: src/modular/observable/publish.js
================================================
'use strict';
var Subject = require('../subject');
var multicast = require('./multicast');
var isFunction = require('../helpers/isfunction');
/**
* Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence.
* This operator is a specialization of Multicast using a regular Subject.
* @param {Function} [selector] Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all notifications of the source from the time of the subscription on.
* @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.
*/
module.exports = function publish (source, fn) {
return fn && isFunction(fn) ?
multicast(source, function () { return new Subject(); }, fn) :
multicast(source, new Subject());
};
================================================
FILE: src/modular/observable/publishlast.js
================================================
'use strict';
var AsyncSubject = require('../asyncsubject');
var multicast = require('./multicast');
var isFunction = require('../helpers/isfunction');
module.exports = function publishLast (source, selector) {
return isFunction(selector) ?
multicast(source, function () { return new AsyncSubject(); }, selector) :
multicast(source, new AsyncSubject());
};
================================================
FILE: src/modular/observable/publishvalue.js
================================================
'use strict';
var multicast = require('./multicast');
var BehaviorSubject = require('../behaviorsubject');
function createBehaviorSubject(initialValue) {
return function fn() { return new BehaviorSubject(initialValue); };
}
module.exports = function publishValue() {
var source = arguments[0];
if (arguments.length === 3) {
return multicast(source, createBehaviorSubject(arguments[2]), arguments[1]);
} else if (arguments.length === 2) {
return multicast(source, new BehaviorSubject(arguments[1]));
} else {
throw new Error('Invalid arguments');
}
};
================================================
FILE: src/modular/observable/race.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var never = require('./never');
var inherits = require('inherits');
var LEFT_CHOICE = 'L';
var RIGHT_CHOICE = 'R';
function choiceL(state) {
if (!state.choice) {
state.choice = LEFT_CHOICE;
state.rightSubscription.dispose();
}
}
function choiceR(state) {
if (!state.choice) {
state.choice = RIGHT_CHOICE;
state.leftSubscription.dispose();
}
}
function LeftObserver(o, state) {
this._o = o;
this._s = state;
AbstractObserver.call(this);
}
inherits(LeftObserver, AbstractObserver);
LeftObserver.prototype.next = function (x) {
choiceL(this._s);
this._s.choice === LEFT_CHOICE && this._o.onNext(x);
};
LeftObserver.prototype.error = function (e) {
choiceL(this._s);
this._s.choice === LEFT_CHOICE && this._o.onError(e);
};
LeftObserver.prototype.completed = function () {
choiceL(this._s);
this._s.choice === LEFT_CHOICE && this._o.onCompleted();
};
function RightObserver(o, state) {
this._o = o;
this._s = state;
AbstractObserver.call(this);
}
inherits(RightObserver, AbstractObserver);
RightObserver.prototype.next = function (x) {
choiceR(this._s);
this._s.choice === RIGHT_CHOICE && this._o.onNext(x);
};
RightObserver.prototype.error = function (e) {
choiceR(this._s);
this._s.choice === RIGHT_CHOICE && this._o.onError(e);
};
RightObserver.prototype.completed = function () {
choiceR(this._s);
this._s.choice === RIGHT_CHOICE && this._o.onCompleted();
};
function AmbObservable (leftSource, rightSource) {
isPromise(leftSource) && (leftSource = fromPromise(leftSource));
isPromise(rightSource) && (rightSource = fromPromise(rightSource));
this._l = leftSource;
this._r = rightSource;
ObservableBase.call(this);
}
inherits(AmbObservable, ObservableBase);
AmbObservable.prototype.subscribeCore = function (o) {
var state = {
choice: null,
leftSubscription: new SingleAssignmentDisposable(),
rightSubscription: new SingleAssignmentDisposable()
};
state.leftSubscription.setDisposable(this._l.subscribe(new LeftObserver(o, state)));
state.rightSubscription.setDisposable(this._r.subscribe(new RightObserver(o, state)));
return new BinaryDisposable(state.leftSubscription, state.rightSubscription);
};
/**
* Propagates the observable sequence or Promise that reacts first.
* @returns {Observable} An observable sequence that surfaces any of the given sequences, whichever reacted first.
*/
module.exports = function amb() {
var acc = never();
for (var i = 0, len = arguments.length; i < len; i++) { acc = new AmbObservable(acc, arguments[i]); }
return acc;
};
================================================
FILE: src/modular/observable/range.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var Scheduler = require('../scheduler');
var inherits = require('inherits');
function RangeObservable(start, count, scheduler) {
this.start = start;
this.rangeCount = count;
this.scheduler = scheduler;
ObservableBase.call(this);
}
inherits(RangeObservable, ObservableBase);
function loopRecursive(start, count, o) {
return function loop (i, recurse) {
if (i < count) {
o.onNext(start + i);
recurse(i + 1);
} else {
o.onCompleted();
}
};
}
RangeObservable.prototype.subscribeCore = function (o) {
return this.scheduler.scheduleRecursive(
0,
loopRecursive(this.start, this.rangeCount, o)
);
};
/**
* Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages.
* @param {Number} start The value of the first integer in the sequence.
* @param {Number} count The number of sequential integers to generate.
* @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread.
* @returns {Observable} An observable sequence that contains a range of sequential integral numbers.
*/
module.exports = function range(start, count, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new RangeObservable(start, count, scheduler);
};
================================================
FILE: src/modular/observable/reduce.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var inherits = require('inherits');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
var EmptyError = require('../internal/errors').EmptyError;
function ReduceObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
AbstractObserver.call(this);
}
inherits(ReduceObserver, AbstractObserver);
ReduceObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._i++;
};
ReduceObserver.prototype.error = function (e) { this._o.onError(e); };
ReduceObserver.prototype.completed = function () {
this._hv && this._o.onNext(this._a);
!this._hv && this._hs && this._o.onNext(this._s);
!this._hv && !this._hs && this._o.onError(new EmptyError());
this._o.onCompleted();
};
function ReduceObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
ObservableBase.call(this);
}
inherits(ReduceObservable, ObservableBase);
ReduceObservable.prototype.subscribeCore = function(observer) {
return this.source.subscribe(new ReduceObserver(observer,this));
};
/**
* Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value.
* For aggregation behavior with incremental intermediate results, see Observable.scan.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @param {Any} [seed] The initial accumulator value.
* @returns {Observable} An observable sequence containing a single element with the final accumulator value.
*/
module.exports = function reduce () {
var hasSeed = false, seed, source = arguments[0], accumulator = arguments[1];
if (arguments.length === 3) {
hasSeed = true;
seed = arguments[2];
}
return new ReduceObservable(source, accumulator, hasSeed, seed);
};
================================================
FILE: src/modular/observable/repeat.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var AbstractObserver = require('../observer/abstractobserver');
var Scheduler = require('../scheduler');
var NAryDisposable = require('../narydisposable');
var SerialDisposable = require('../serialdisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var inherits = require('inherits');
var $iterator$ = '@@iterator';
function repeatValue(value, count) {
count == null && (count = -1);
return {
'@@iterator': function () {
return {
remaining: count,
next: function () {
if (this.remaining === 0) { return { done: true, value: undefined }; }
if (this.remaining > 0) { this.remaining--; }
return { done: false, value: value };
}
};
}
};
}
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function ConcatObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(ConcatObserver, AbstractObserver);
ConcatObserver.prototype.next = function (x) { this._state.o.onNext(x); };
ConcatObserver.prototype.error = function (e) { this._state.o.onError(e); };
ConcatObserver.prototype.completed = function () { this._recurse(this._state); };
function ConcatObservable(sources) {
this.sources = sources;
ObservableBase.call(this);
}
inherits(ConcatObservable, ObservableBase);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = state.e.next();
if (currentItem.done) { return state.o.onCompleted(); }
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new ConcatObserver(state, recurse)));
}
ConcatObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
o: o,
subscription: subscription,
e: this.sources[$iterator$]()
};
var cancelable = Scheduler.queue.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, createDisposable(state)]);
};
module.exports = function repeat(source, repeatCount) {
return new ConcatObservable(repeatValue(source, repeatCount));
};
================================================
FILE: src/modular/observable/repeatvalue.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var Scheduler = require('../scheduler');
var inherits = require('inherits');
function RepeatValueObservable(value, count, scheduler) {
this._value = value;
this._count = count;
this._scheduler = scheduler;
ObservableBase.call(this);
}
inherits(RepeatValueObservable, ObservableBase);
function scheduleRecursive(state, recurse) {
if (state.n === 0) { return state.o.onCompleted(); }
if (state.n > 0) { state.n--; }
state.o.onNext(state.value);
recurse(state);
}
RepeatValueObservable.prototype.subscribeCore = function (o) {
var state = {
value: this._value,
n: this._count,
o: o
};
return this._scheduler.scheduleRecursive(state, scheduleRecursive);
};
module.exports = function repeatValue (value, repeatCount, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.queue);
return new RepeatValueObservable(value, repeatCount, scheduler);
};
================================================
FILE: src/modular/observable/repeatwhen.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var Subject = require('../subject');
var Scheduler = require('../scheduler');
var BinaryDisposable = require('../binarydisposable');
var NAryDisposable = require('../narydisposable');
var SerialDisposable = require('../serialdisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var inherits = require('inherits');
var $iterator$ = '@@iterator';
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function RepeatWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
ObservableBase.call(this);
}
inherits(RepeatWhenObservable, ObservableBase);
RepeatWhenObservable.prototype.subscribeCore = function (o) {
var completions = new Subject(),
notifier = new Subject(),
handled = this._notifier(completions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source[$iterator$]();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = Scheduler.queue.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) { o.onError(exn); },
function() {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
completions.onNext(null);
outer.dispose();
}));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
module.exports = function repeatWhen (source, notifier) {
return new RepeatWhenObservable(repeat(source), notifier);
};
================================================
FILE: src/modular/observable/replay.js
================================================
'use strict';
var multicast = require('./multicast');
var ReplaySubject = require('../replaysubject');
var isFunction = require('../helpers/isfunction');
module.exports = function replay (source, selector, bufferSize, windowSize, scheduler) {
return isFunction(selector) ?
multicast(source, function () { return new ReplaySubject(bufferSize, windowSize, scheduler); }, selector) :
multicast(source, new ReplaySubject(bufferSize, windowSize, scheduler));
};
================================================
FILE: src/modular/observable/retry.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var AbstractObserver = require('../observer/abstractobserver');
var Scheduler = require('../scheduler');
var NAryDisposable = require('../narydisposable');
var SerialDisposable = require('../serialdisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var inherits = require('inherits');
var $iterator$ = '@@iterator';
function repeat(value, count) {
count == null && (count = -1);
return {
'@@iterator': function () {
return {
remaining: count,
next: function () {
if (this.remaining === 0) { return { done: true, value: undefined }; }
if (this.remaining > 0) { this.remaining--; }
return { done: false, value: value };
}
};
}
};
}
function CatchErrorObserver(state, recurse) {
this._state = state;
this._recurse = recurse;
AbstractObserver.call(this);
}
inherits(CatchErrorObserver, AbstractObserver);
CatchErrorObserver.prototype.next = function (x) { this._state.o.onNext(x); };
CatchErrorObserver.prototype.error = function (e) { this._state.lastError = e; this._recurse(this._state); };
CatchErrorObserver.prototype.completed = function () { this._state.o.onCompleted(); };
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function CatchErrorObservable(sources) {
this.sources = sources;
ObservableBase.call(this);
}
inherits(CatchErrorObservable, ObservableBase);
function scheduleMethod(state, recurse) {
if (state.isDisposed) { return; }
var currentItem = state.e.next();
if (currentItem.done) { return state.lastError !== null ? state.o.onError(state.lastError) : state.o.onCompleted(); }
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var d = new SingleAssignmentDisposable();
state.subscription.setDisposable(d);
d.setDisposable(currentValue.subscribe(new CatchErrorObserver(state, recurse)));
}
CatchErrorObservable.prototype.subscribeCore = function (o) {
var subscription = new SerialDisposable();
var state = {
isDisposed: false,
e: this.sources[$iterator$](),
subscription: subscription,
lastError: null,
o: o
};
var cancelable = Scheduler.queue.scheduleRecursive(state, scheduleMethod);
return new NAryDisposable([subscription, cancelable, createDisposable(state)]);
};
module.exports = function retry(source, retryCount) {
return new CatchErrorObservable(repeat(source, retryCount));
};
================================================
FILE: src/modular/observable/retrywhen.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var Subject = require('../subject');
var Scheduler = require('../scheduler');
var BinaryDisposable = require('../binarydisposable');
var NAryDisposable = require('../narydisposable');
var SerialDisposable = require('../serialdisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var inherits = require('inherits');
var $iterator$ = '@@iterator';
function repeat(value) {
return {
'@@iterator': function () {
return {
next: function () {
return { done: false, value: value };
}
};
}
};
}
function createDisposable(state) {
return {
isDisposed: false,
dispose: function () {
if (!this.isDisposed) {
this.isDisposed = true;
state.isDisposed = true;
}
}
};
}
function CatchErrorWhenObservable(source, notifier) {
this.source = source;
this._notifier = notifier;
ObservableBase.call(this);
}
inherits(CatchErrorWhenObservable, ObservableBase);
CatchErrorWhenObservable.prototype.subscribeCore = function (o) {
var exceptions = new Subject(),
notifier = new Subject(),
handled = this._notifier(exceptions),
notificationDisposable = handled.subscribe(notifier);
var e = this.source[$iterator$]();
var state = { isDisposed: false },
lastError,
subscription = new SerialDisposable();
var cancelable = Scheduler.queue.scheduleRecursive(null, function (_, recurse) {
if (state.isDisposed) { return; }
var currentItem = e.next();
if (currentItem.done) {
if (lastError) {
o.onError(lastError);
} else {
o.onCompleted();
}
return;
}
// Check if promise
var currentValue = currentItem.value;
isPromise(currentValue) && (currentValue = fromPromise(currentValue));
var outer = new SingleAssignmentDisposable();
var inner = new SingleAssignmentDisposable();
subscription.setDisposable(new BinaryDisposable(inner, outer));
outer.setDisposable(currentValue.subscribe(
function(x) { o.onNext(x); },
function (exn) {
inner.setDisposable(notifier.subscribe(recurse, function(ex) {
o.onError(ex);
}, function() {
o.onCompleted();
}));
exceptions.onNext(exn);
outer.dispose();
},
function() { o.onCompleted(); }));
});
return new NAryDisposable([notificationDisposable, subscription, cancelable, createDisposable(state)]);
};
module.exports = function retryWhen (source, notifier) {
return new CatchErrorWhenObservable(repeat(source), notifier);
};
================================================
FILE: src/modular/observable/sample.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var interval = require('./interval');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var Scheduler = require('../scheduler');
var inherits = require('inherits');
function SamplerObserver(s) {
this._s = s;
AbstractObserver.call(this);
}
inherits(SamplerObserver, AbstractObserver);
SamplerObserver.prototype._handleMessage = function () {
if (this._s.hasValue) {
this._s.hasValue = false;
this._s.o.onNext(this._s.value);
}
this._s.atEnd && this._s.o.onCompleted();
};
SamplerObserver.prototype.next = function () { this._handleMessage(); };
SamplerObserver.prototype.error = function (e) { this._s.onError(e); };
SamplerObserver.prototype.completed = function () { this._handleMessage(); };
function SampleSourceObserver(s) {
this._s = s;
AbstractObserver.call(this);
}
inherits(SampleSourceObserver, AbstractObserver);
SampleSourceObserver.prototype.next = function (x) {
this._s.hasValue = true;
this._s.value = x;
};
SampleSourceObserver.prototype.error = function (e) { this._s.o.onError(e); };
SampleSourceObserver.prototype.completed = function () {
this._s.atEnd = true;
this._s.sourceSubscription.dispose();
};
function SampleObservable(source, sampler) {
this.source = source;
this._sampler = sampler;
ObservableBase.call(this);
}
inherits(SampleObservable, ObservableBase);
SampleObservable.prototype.subscribeCore = function (o) {
var state = {
o: o,
atEnd: false,
value: null,
hasValue: false,
sourceSubscription: new SingleAssignmentDisposable()
};
state.sourceSubscription.setDisposable(this.source.subscribe(new SampleSourceObserver(state)));
return new BinaryDisposable(
state.sourceSubscription,
this._sampler.subscribe(new SamplerObserver(state))
);
};
module.exports = function sample(source, intervalOrSampler, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return typeof intervalOrSampler === 'number' ?
new SampleObservable(source, interval(intervalOrSampler, scheduler)) :
new SampleObservable(source, intervalOrSampler);
};
================================================
FILE: src/modular/observable/scan.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var inherits = require('inherits');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
function ScanObserver(o, parent) {
this._o = o;
this._p = parent;
this._fn = parent.accumulator;
this._hs = parent.hasSeed;
this._s = parent.seed;
this._ha = false;
this._a = null;
this._hv = false;
this._i = 0;
AbstractObserver.call(this);
}
inherits(ScanObserver, AbstractObserver);
ScanObserver.prototype.next = function (x) {
!this._hv && (this._hv = true);
if (this._ha) {
this._a = tryCatch(this._fn)(this._a, x, this._i, this._p);
} else {
this._a = this._hs ? tryCatch(this._fn)(this._s, x, this._i, this._p) : x;
this._ha = true;
}
if (this._a === errorObj) { return this._o.onError(this._a.e); }
this._o.onNext(this._a);
this._i++;
};
ScanObserver.prototype.error = function (e) { this._o.onError(e); };
ScanObserver.prototype.completed = function () {
!this._hv && this._hs && this._o.onNext(this._s);
this._o.onCompleted();
};
function ScanObservable(source, accumulator, hasSeed, seed) {
this.source = source;
this.accumulator = accumulator;
this.hasSeed = hasSeed;
this.seed = seed;
ObservableBase.call(this);
}
inherits(ScanObservable, ObservableBase);
ScanObservable.prototype.subscribeCore = function(o) {
return this.source.subscribe(new ScanObserver(o,this));
};
/**
* Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value.
* For aggregation behavior with no intermediate results, see Observable.aggregate.
* @param {Mixed} [seed] The initial accumulator value.
* @param {Function} accumulator An accumulator function to be invoked on each element.
* @returns {Observable} An observable sequence containing the accumulated values.
*/
module.exports = function scan () {
var source = arguments[0], hasSeed = false, seed, accumulator = arguments[1];
if (arguments.length === 3) {
hasSeed = true;
seed = arguments[2];
}
return new ScanObservable(source, accumulator, hasSeed, seed);
};
================================================
FILE: src/modular/observable/sequenceequal.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var fromArray = require('./from');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var isEqual = require('../internal/isequal');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
var inherits = require('inherits');
var $iterator$ = (typeof global.Symbol === 'function' && global.Symbol.iterator) ||
'_es6shim_iterator_';
// Bug for mozilla version
if (global.Set && typeof new global.Set()['@@iterator'] === 'function') {
$iterator$ = '@@iterator';
}
function isIterable(o) {
return o && o[$iterator$] !== undefined;
}
function isArrayLike (o) {
return o && o.length !== undefined;
}
function FirstObserver(state) {
this._s = state;
AbstractObserver.call(this);
}
inherits(FirstObserver, AbstractObserver);
FirstObserver.prototype.next = function (x) {
if (this._s.qr.length > 0) {
var v = this._s.qr.shift();
var equal = tryCatch(this._s.cmp)(v, x);
if (equal === errorObj) { return this._s.o.onError(equal.e); }
if (!equal) {
this._s.o.onNext(false);
this._s.o.onCompleted();
}
} else if (this._s.doner) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else {
this._s.ql.push(x);
}
};
FirstObserver.prototype.error = function (e) { this._s.o.onError(e); };
FirstObserver.prototype.completed = function () {
this._s.donel = true;
if (this._s.ql.length === 0) {
if (this._s.qr.length > 0) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else if (this._s.doner) {
this._s.o.onNext(true);
this._s.o.onCompleted();
}
}
};
function SecondObserver(state) {
this._s = state;
AbstractObserver.call(this);
}
inherits(SecondObserver, AbstractObserver);
SecondObserver.prototype.next = function (x) {
if (this._s.ql.length > 0) {
var v = this._s.ql.shift();
var equal = tryCatch(this._s.cmp)(v, x);
if (equal === errorObj) { return this._s.o.onError(equal.e); }
if (!equal) {
this._s.o.onNext(false);
this._s.o.onCompleted();
}
} else if (this._s.donel) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else {
this._s.qr.push(x);
}
};
SecondObserver.prototype.error = function (e) { this._s.o.onError(e); };
SecondObserver.prototype.completed = function () {
this._s.doner = true;
if (this._s.qr.length === 0) {
if (this._s.ql.length > 0) {
this._s.o.onNext(false);
this._s.o.onCompleted();
} else if (this._s.donel) {
this._s.o.onNext(true);
this._s.o.onCompleted();
}
}
};
function SequenceEqualObservable(first, second, comparer) {
this._first = first;
this._second = second;
this._cmp = comparer;
ObservableBase.call(this);
}
inherits(SequenceEqualObservable, ObservableBase);
SequenceEqualObservable.prototype.subscribeCore = function (o) {
(isArrayLike(this._first) || isIterable(this._first)) && (this._first = fromArray(this._first));
isPromise(this._first) && (this._first = fromPromise(this._first));
(isArrayLike(this._second) || isIterable(this._second)) && (this._second = fromArray(this._second));
isPromise(this._second) && (this._second = fromPromise(this._second));
var state = {
o: o,
donel: false,
doner: false,
ql: [],
qr: [],
cmp: this._cmp
};
return new BinaryDisposable(
this._first.subscribe(new FirstObserver(state)),
this._second.subscribe(new SecondObserver(state))
);
};
module.exports = function sequenceEqual (first, second, comparer) {
comparer || (comparer = isEqual);
return new SequenceEqualObservable(first, second, comparer);
};
================================================
FILE: src/modular/observable/share.js
================================================
'use strict';
var publish = require('./publish');
module.exports = function share (source) {
return publish(source).refCount();
};
================================================
FILE: src/modular/observable/sharereplay.js
================================================
'use strict';
var replay = require('./replay');
module.exports = function shareReplay(source, bufferSize, windowSize, scheduler) {
return replay(source, null, bufferSize, windowSize, scheduler).refCount();
};
================================================
FILE: src/modular/observable/sharevalue.js
================================================
'use strict';
var publishValue = require('./publishvalue');
module.exports = function shareValue(source, initialValue) {
return publishValue(source, initialValue).refCount();
};
================================================
FILE: src/modular/observable/skip.js
================================================
'use strict';
var AbstractObserver = require('../observer/abstractobserver');
var ObservableBase = require('./observablebase');
var errors = require('../internal/errors');
var inherits = require('inherits');
function SkipObserver(o, r) {
this._o = o;
this._r = r;
AbstractObserver.call(this);
}
inherits(SkipObserver, AbstractObserver);
SkipObserver.prototype.next = function (x) {
if (this._r <= 0) {
this._o.onNext(x);
} else {
this._r--;
}
};
SkipObserver.prototype.error = function(e) { this._o.onError(e); };
SkipObserver.prototype.completed = function() { this._o.onCompleted(); };
function SkipObservable(source, count) {
this.source = source;
this._count = count;
ObservableBase.call(this);
}
inherits(SkipObservable, ObservableBase);
SkipObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipObserver(o, this._count));
};
/**
* Bypasses a specified number of elements in an observable sequence and then returns the remaining elements.
* @param {Number} count The number of elements to skip before returning the remaining elements.
* @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence.
*/
module.exports = function skip(source, count) {
if (count < 0) { throw new errors.ArgumentOutOfRangeError(); }
return new SkipObservable(source, count);
};
================================================
FILE: src/modular/observable/skiplast.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var inherits = require('inherits');
function SkipLastObserver(o, c) {
this._o = o;
this._c = c;
this._q = [];
AbstractObserver.call(this);
}
inherits(SkipLastObserver, AbstractObserver);
SkipLastObserver.prototype.next = function (x) {
this._q.push(x);
this._q.length > this._c && this._o.onNext(this._q.shift());
};
SkipLastObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastObserver.prototype.completed = function () { this._o.onCompleted(); };
function SkipLastObservable(source, c) {
this.source = source;
this._c = c;
ObservableBase.call(this);
}
inherits(SkipLastObservable, ObservableBase);
SkipLastObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastObserver(o, this._c));
};
module.exports = function skipLast (source, count) {
count < 0 && (count = 0);
return new SkipLastObservable(source, count);
};
================================================
FILE: src/modular/observable/skiplastwithtime.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var Scheduler = require('../scheduler');
var inherits = require('inherits');
function SkipLastWithTimeObserver(o, p) {
this._o = o;
this._s = p._s;
this._d = p._d;
this._q = [];
AbstractObserver.call(this);
}
inherits(SkipLastWithTimeObserver, AbstractObserver);
SkipLastWithTimeObserver.prototype.next = function (x) {
var now = this._s.now();
this._q.push({ interval: now, value: x });
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
};
SkipLastWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipLastWithTimeObserver.prototype.completed = function () {
var now = this._s.now();
while (this._q.length > 0 && now - this._q[0].interval >= this._d) {
this._o.onNext(this._q.shift().value);
}
this._o.onCompleted();
};
function SkipLastWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
ObservableBase.call(this);
}
inherits(SkipLastWithTimeObservable, ObservableBase);
SkipLastWithTimeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipLastWithTimeObserver(o, this));
};
module.exports = function skipLastWithTime (source, duration, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return new SkipLastWithTimeObservable(source, duration, scheduler);
};
================================================
FILE: src/modular/observable/skipuntil.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var inherits = require('inherits');
function SkipUntilSourceObserver(o, p) {
this._o = o;
this._p = p;
AbstractObserver.call(this);
}
inherits(SkipUntilSourceObserver, AbstractObserver);
SkipUntilSourceObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilSourceObserver.prototype.error = function (err) { this._o.onError(err); };
SkipUntilSourceObserver.prototype.onCompleted = function () { this._p._open && this._o.onCompleted(); };
function SkipUntilOtherObserver(o, p, r) {
this._o = o;
this._p = p;
this._r = r;
AbstractObserver.call(this);
}
inherits(SkipUntilOtherObserver, AbstractObserver);
SkipUntilOtherObserver.prototype.next = function () { this._p._open = true; this._r.dispose(); };
SkipUntilOtherObserver.prototype.error = function (err) { this._o.onError(err); };
SkipUntilOtherObserver.prototype.onCompleted = function () { this._r.dispose(); };
function SkipUntilObservable(source, other) {
this._s = source;
this._o = isPromise(other) ? fromPromise(other) : other;
this._open = false;
ObservableBase.call(this);
}
inherits(SkipUntilObservable, ObservableBase);
SkipUntilObservable.prototype.subscribeCore = function(o) {
var leftSubscription = new SingleAssignmentDisposable();
leftSubscription.setDisposable(this._s.subscribe(new SkipUntilSourceObserver(o, this)));
isPromise(this._o) && (this._o = fromPromise(this._o));
var rightSubscription = new SingleAssignmentDisposable();
rightSubscription.setDisposable(this._o.subscribe(new SkipUntilOtherObserver(o, this, rightSubscription)));
return new BinaryDisposable(leftSubscription, rightSubscription);
};
/**
* Returns the values from the source observable sequence only after the other observable sequence produces a value.
* @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence.
* @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation.
*/
module.exports = function skipUntil (source, other) {
return new SkipUntilObservable(source, other);
};
================================================
FILE: src/modular/observable/skipuntilwithtime.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var Scheduler = require('../scheduler');
var inherits = require('inherits');
function SkipUntilWithTimeObserver(o, p) {
this._o = o;
this._p = p;
AbstractObserver.call(this);
}
inherits(SkipUntilWithTimeObserver, AbstractObserver);
SkipUntilWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipUntilWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipUntilWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
function SkipUntilWithTimeObservable(source, startTime, scheduler) {
this.source = source;
this._st = startTime;
this._s = scheduler;
ObservableBase.call(this);
}
inherits(SkipUntilWithTimeObservable, ObservableBase);
function scheduleMethod(s, state) {
state._open = true;
}
SkipUntilWithTimeObservable.prototype.subscribeCore = function (o) {
this._open = false;
return new BinaryDisposable(
this._s.scheduleFuture(this, this._st, scheduleMethod),
this.source.subscribe(new SkipUntilWithTimeObserver(o, this))
);
};
module.exports = function skipUntilWithTime (source, startTime, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return new SkipUntilWithTimeObservable(source, startTime, scheduler);
};
================================================
FILE: src/modular/observable/skipwhile.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var bindCallback = require('../internal/bindcallback');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
var inherits = require('inherits');
function SkipWhileObserver(o, p) {
this._o = o;
this._p = p;
this._i = 0;
this._r = false;
AbstractObserver.call(this);
}
inherits(SkipWhileObserver, AbstractObserver);
SkipWhileObserver.prototype.next = function (x) {
if (!this._r) {
var res = tryCatch(this._p._fn)(x, this._i++, this._p);
if (res === errorObj) { return this._o.onError(res.e); }
this._r = !res;
}
this._r && this._o.onNext(x);
};
SkipWhileObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWhileObserver.prototype.completed = function () { this._o.onCompleted(); };
function SkipWhileObservable(source, fn) {
this.source = source;
this._fn = fn;
ObservableBase.call(this);
}
inherits(SkipWhileObservable, ObservableBase);
SkipWhileObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SkipWhileObserver(o, this));
};
module.exports = function skipWhile (source, predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SkipWhileObservable(source, fn);
};
================================================
FILE: src/modular/observable/skipwithtime.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var Scheduler = require('../scheduler');
var inherits = require('inherits');
function SkipWithTimeObserver(o, p) {
this._o = o;
this._p = p;
AbstractObserver.call(this);
}
inherits(SkipWithTimeObserver, AbstractObserver);
SkipWithTimeObserver.prototype.next = function (x) { this._p._open && this._o.onNext(x); };
SkipWithTimeObserver.prototype.error = function (e) { this._o.onError(e); };
SkipWithTimeObserver.prototype.completed = function () { this._o.onCompleted(); };
function SkipWithTimeObservable(source, d, s) {
this.source = source;
this._d = d;
this._s = s;
this._open = false;
ObservableBase.call(this);
}
inherits(SkipWithTimeObservable, ObservableBase);
function scheduleMethod(s, self) {
self._open = true;
}
SkipWithTimeObservable.prototype.subscribeCore = function (o) {
return new BinaryDisposable(
this._s.scheduleFuture(this, this._d, scheduleMethod),
this.source.subscribe(new SkipWithTimeObserver(o, this))
);
};
module.exports = function skipWithTime (source, duration, scheduler) {
Scheduler.isScheduler(scheduler) || (scheduler = Scheduler.async);
return new SkipWithTimeObservable(source, duration, scheduler);
};
================================================
FILE: src/modular/observable/slice.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var ArgumentOutOfRangeError = require('../internal/errors').ArgumentOutOfRangeError;
var inherits = require('inherits');
function SliceObserver(o, b, e) {
this._o = o;
this._b = b;
this._e = e;
this._i = 0;
AbstractObserver.call(this);
}
inherits(SliceObserver, AbstractObserver);
SliceObserver.prototype.next = function (x) {
if (this._i >= this._b) {
if (this._e === this._i) {
this._o.onCompleted();
} else {
this._o.onNext(x);
}
}
this._i++;
};
SliceObserver.prototype.error = function (e) { this._o.onError(e); };
SliceObserver.prototype.completed = function () { this._o.onCompleted(); };
function SliceObservable(source, b, e) {
this.source = source;
this._b = b;
this._e = e;
ObservableBase.call(this);
}
inherits(SliceObservable, ObservableBase);
SliceObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SliceObserver(o, this._b, this._e));
};
module.exports = function slice(source, begin, end) {
var start = begin || 0;
if (start < 0) { throw new ArgumentOutOfRangeError(); }
if (typeof end === 'number' && end < start) {
throw new ArgumentOutOfRangeError();
}
return new SliceObservable(source, start, end);
};
================================================
FILE: src/modular/observable/some.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var bindCallback = require('../internal/bindcallback');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
var inherits = require('inherits');
function SomeObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
AbstractObserver.call(this);
}
inherits(SomeObserver, AbstractObserver);
SomeObserver.prototype.next = function (x) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
if (Boolean(result)) {
this._o.onNext(true);
this._o.onCompleted();
}
};
SomeObserver.prototype.error = function (e) { this._o.onError(e); };
SomeObserver.prototype.completed = function () {
this._o.onNext(false);
this._o.onCompleted();
};
function SomeObservable(source, fn) {
this.source = source;
this._fn = fn;
ObservableBase.call(this);
}
inherits(SomeObservable, ObservableBase);
SomeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SomeObserver(o, this._fn, this.source));
};
module.exports = function some (source, predicate, thisArg) {
var fn = bindCallback(predicate, thisArg, 3);
return new SomeObservable(source, fn);
};
================================================
FILE: src/modular/observable/start.js
================================================
'use strict';
var toAsync = require('./toasync');
module.exports = function start (func, context, scheduler) {
return toAsync(func, context, scheduler)();
};
================================================
FILE: src/modular/observable/startasync.js
================================================
'use strict';
var fromPromise = require('./frompromise');
var throwError = require('./throw');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
module.exports = function startAsync(functionAsync) {
var promise = tryCatch(functionAsync)();
if (promise === errorObj) { return throwError(promise.e); }
return fromPromise(promise);
};
================================================
FILE: src/modular/observable/startwith.js
================================================
'use strict';
var concat = require('./concat');
var fromArray = require('./fromarray');
var Scheduler = require('../scheduler');
module.exports = function startWith () {
var source = arguments[0], scheduler, start = 1;
if (Scheduler.isScheduler(arguments[1])) {
scheduler = arguments[1];
start = 2;
} else {
scheduler = Scheduler.immediate;
}
for(var args = [], i = start, len = arguments.length; i < len; i++) { args.push(arguments[i]); }
return concat(fromArray(args, scheduler), source);
};
================================================
FILE: src/modular/observable/stopandwait.js
================================================
'use strict';
var Observable = require('../observable');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var inherits = require('inherits');
function StopAndWaitObserver(observer, observable, scheduler, cancel) {
this.observer = observer;
this.observable = observable;
this.scheduler = scheduler;
this.cancel = cancel;
this.scheduleDisposable = null;
AbstractObserver.call(this);
}
inherits(StopAndWaitObserver, AbstractObserver);
StopAndWaitObserver.prototype.completed = function () {
this.observer.onCompleted();
this.dispose();
};
StopAndWaitObserver.prototype.error = function (error) {
this.observer.onError(error);
this.dispose();
};
function innerScheduleMethod(s, self) {
return self.observable.source.request(1);
}
StopAndWaitObserver.prototype.next = function (value) {
this.observer.onNext(value);
this.scheduleDisposable = this.scheduler.schedule(this, innerScheduleMethod);
};
StopAndWaitObserver.prototype.dispose = function () {
this.observer = null;
if (this.cancel) {
this.cancel.dispose();
this.cancel = null;
}
if (this.scheduleDisposable) {
this.scheduleDisposable.dispose();
this.scheduleDisposable = null;
}
AbstractObserver.prototype.dispose.call(this);
};
function StopAndWaitObservable(source, scheduler) {
this.source = source;
this.scheduler = scheduler;
Observable.call(this);
}
inherits(StopAndWaitObservable, Observable);
function scheduleMethod(s, self) {
return self.source.request(1);
}
StopAndWaitObservable.prototype._subscribe = function (o) {
this.subscription = this.source.subscribe(new StopAndWaitObserver(o, this, this.scheduler, this.subscription));
return new BinaryDisposable(
this.subscription,
this.scheduler.schedule(this, scheduleMethod)
);
};
module.exports = StopAndWaitObservable;
================================================
FILE: src/modular/observable/subscribeon.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var ScheduledDisposable = require('../scheduleddisposable');
var SerialDisposable = require('../serialdisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var inherits = require('inherits');
function SubscribeOnObservable(source, s) {
this.source = source;
this._s = s;
ObservableBase.call(this);
}
inherits(SubscribeOnObservable, ObservableBase);
function scheduleMethod(scheduler, state) {
var source = state[0], d = state[1], o = state[2];
d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(o)));
}
SubscribeOnObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(), d = new SerialDisposable();
d.setDisposable(m);
m.setDisposable(this._s.schedule([this.source, d, o], scheduleMethod));
return d;
};
module.exports = function subscribeOn (source, scheduler) {
return new SubscribeOnObservable(source, scheduler);
};
================================================
FILE: src/modular/observable/sum.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var bindCallback = require('../internal/bindcallback');
var tryCatchUtils = require('../internal/trycatchutils');
var tryCatch = tryCatchUtils.tryCatch, errorObj = tryCatchUtils.errorObj;
var inherits = require('inherits');
function SumObserver(o, fn, s) {
this._o = o;
this._fn = fn;
this._s = s;
this._i = 0;
this._c = 0;
AbstractObserver.call(this);
}
inherits(SumObserver, AbstractObserver);
SumObserver.prototype.next = function (x) {
if (this._fn) {
var result = tryCatch(this._fn)(x, this._i++, this._s);
if (result === errorObj) { return this._o.onError(result.e); }
this._c += result;
} else {
this._c += x;
}
};
SumObserver.prototype.error = function (e) { this._o.onError(e); };
SumObserver.prototype.completed = function () {
this._o.onNext(this._c);
this._o.onCompleted();
};
function SumObservable(source, fn) {
this.source = source;
this._fn = fn;
ObservableBase.call(this);
}
inherits(SumObservable, ObservableBase);
SumObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new SumObserver(o, this._fn, this.source));
};
module.exports = function sum (source, keySelector, thisArg) {
var fn = bindCallback(keySelector, thisArg, 3);
return new SumObservable(source, fn);
};
================================================
FILE: src/modular/observable/switch.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var BinaryDisposable = require('../binarydisposable');
var SerialDisposable = require('../serialdisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var inherits = require('inherits');
function InnerObserver(p, id) {
this._p = p;
this._id = id;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._p._latest === this._id && this._p._o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._p._latest === this._id && this._p._o.onError(e); };
InnerObserver.prototype.completed = function () {
if (this._p._latest === this._id) {
this._p._hasLatest = false;
this._p._stopped && this._p._o.onCompleted();
}
};
function SwitchObserver(o, inner) {
this._o = o;
this._inner = inner;
this._stopped = false;
this._latest = 0;
this._hasLatest = false;
AbstractObserver.call(this);
}
inherits(SwitchObserver, AbstractObserver);
SwitchObserver.prototype.next = function (innerSource) {
var d = new SingleAssignmentDisposable(), id = ++this._latest;
this._hasLatest = true;
this._inner.setDisposable(d);
isPromise(innerSource) && (innerSource = fromPromise(innerSource));
d.setDisposable(innerSource.subscribe(new InnerObserver(this, id)));
};
SwitchObserver.prototype.error = function (e) { this._o.onError(e); };
SwitchObserver.prototype.completed = function () { this._stopped = true; !this._hasLatest && this._o.onCompleted(); };
function SwitchObservable(source) {
this.source = source;
ObservableBase.call(this);
}
inherits(SwitchObservable, ObservableBase);
SwitchObservable.prototype.subscribeCore = function (o) {
var inner = new SerialDisposable(), s = this.source.subscribe(new SwitchObserver(o, inner));
return new BinaryDisposable(s, inner);
};
/**
* Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.
* @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received.
*/
module.exports = function switch_(source) {
return new SwitchObservable(source);
};
================================================
FILE: src/modular/observable/switchfirst.js
================================================
'use strict';
var ObservableBase = require('./observablebase');
var AbstractObserver = require('../observer/abstractobserver');
var CompositeDisposable = require('../compositedisposable');
var SingleAssignmentDisposable = require('../singleassignmentdisposable');
var fromPromise = require('./frompromise');
var isPromise = require('../helpers/ispromise');
var inherits = require('inherits');
function InnerObserver(state, inner) {
this._s = state;
this._i = inner;
AbstractObserver.call(this);
}
inherits(InnerObserver, AbstractObserver);
InnerObserver.prototype.next = function (x) { this._s.o.onNext(x); };
InnerObserver.prototype.error = function (e) { this._s.o.onError(e); };
InnerObserver.prototype.completed = function () {
this._s.g.remove(this._i);
this._s.hasCurrent = false;
this._s.isStopped && this._s.g.length === 1 && this._s.o.onCompleted();
};
function SwitchFirstObserver(state) {
this._s = state;
AbstractObserver.call(this);
}
inherits(SwitchFirstObserver, AbstractObserver);
SwitchFirstObserver.prototype.next = function (x) {
if (!this._s.hasCurrent) {
this._s.hasCurrent = true;
isPromise(x) && (x = fromPromise(x));
var inner = new SingleAssignmentDisposable();
this._s.g.add(inner);
inner.setDisposable(x.subscribe(new InnerObserver(this._s, inner)));
}
};
SwitchFirstObserver.prototype.error = function (e) {
this._s.o.onError(e);
};
SwitchFirstObserver.prototype.completed = function () {
this._s.isStopped = true;
!this._s.hasCurrent && this._s.g.length === 1 && this._s.o.onCompleted();
};
function SwitchFirstObservable(source) {
this.source = source;
ObservableBase.call(this);
}
inherits(SwitchFirstObservable, ObservableBase);
SwitchFirstObservable.prototype.subscribeCore = function (o) {
var m = new SingleAssignmentDisposable(),
g = new CompositeDisposable(),
state = {
hasCurrent: false,
isStopped: false,
o: o,
g: g
};
g.add(m);
m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));
return g;
};
/**
* Performs a exclusive waiting for the first to finish before subscribing to another observable.
* Observables that come in between subscriptions will be dropped on the floor.
* @returns {Observable} A exclusive observable with only the results that happen when subscribed.
*/
module.exports = function switchFirst (source) {
return new SwitchFirstObservable(source);
};
================================================
FILE: src/modular/observable/take.js
================================================
'use strict';
var AbstractObserver = require('../observer/abstractobserver');
var ObservableBase = require('./observablebase');
var empty = require('./empty');
var errors = require('../internal/errors');
var inherits = require('inherits');
function TakeObserver(o, c) {
this._o = o;
this._c = c;
this._r = c;
AbstractObserver.call(this);
}
inherits(TakeObserver, AbstractObserver);
TakeObserver.prototype.next = function (x) {
if (this._r-- > 0) {
this._o.onNext(x);
this._r <= 0 && this._o.onCompleted();
}
};
TakeObserver.prototype.error = function (e) { this._o.onError(e); };
TakeObserver.prototype.completed = function () { this._o.onCompleted(); };
function TakeObservable(source, count) {
this.source = source;
this._count = count;
ObservableBase.call(this);
}
inherits(TakeObservable, ObservableBase);
TakeObservable.prototype.subscribeCore = function (o) {
return this.source.subscribe(new TakeObserver(o, this._count));
};
/**
* Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0).
* @param {Number} count The number of elements to return.
* @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0) {
work = state.queue.shift();
} else {
state.isAcquired = false;
return;
}
var res = tryCatch(work)();
if (res === errorObj) {
state.queue = [];
state.hasFaulted = true;
return thrower(res.e);
}
recurse(state);
}
ScheduledObserver.prototype.ensureActive = function () {
var isOwner = false;
if (!this.hasFaulted && this.queue.length > 0) {
isOwner = !this.isAcquired;
this.isAcquired = true;
}
isOwner &&
this.disposable.setDisposable(this.scheduler.scheduleRecursive(this, scheduleMethod));
};
ScheduledObserver.prototype.dispose = function () {
AbstractObserver.prototype.dispose.call(this);
this.disposable.dispose();
};
module.exports = ScheduledObserver;
================================================
FILE: src/modular/observer/tonotifier.js
================================================
'use strict';
/**
* Creates a notification callback from an observer.
* @returns The action that forwards its input notification to the underlying observer.
*/
module.exports = function (observer) {
return function (n) { return n.accept(observer); };
};
================================================
FILE: src/modular/observer.js
================================================
'use strict';
/**
* Supports push-style iteration over an observable sequence.
*/
function Observer () { }
Observer.addToObject = function (operators) {
Object.keys(operators).forEach(function (operator) {
Observer[operator] = operators[operator];
});
};
Observer.addToPrototype = function (operators) {
Object.keys(operators).forEach(function (operator) {
Observer.prototype[operator] = function () {
var args = [this];
args.push.apply(args, arguments);
return operators[operator].apply(null, args);
};
});
};
module.exports = Observer;
================================================
FILE: src/modular/package.json
================================================
{
"name": "@rxjs/rx",
"version": "4.1.0",
"description": "The Reactive Extensions for JavaScript",
"main": "index.js",
"scripts": {
"build:all:umd:debug": "webpack index.js dist/rx.all.js --config webpack.config.js",
"build:all:umd:min": "webpack index.js dist/rx.all.min.js --config webpack.config.production.js",
"build:all:umd": "npm run build:all:umd:debug && npm run build:all:umd:min",
"build:lite:umd:debug": "webpack rx.lite.js dist/rx.lite.js --config webpack.config.js",
"build:lite:umd:min": "webpack rx.lite.js dist/rx.lite.min.js --config webpack.config.production.js",
"build:lite:umd": "npm run build:lite:umd:debug && npm run build:lite:umd:min",
"build:test": "npm run build:all:umd && npm run build:lite:umd && npm run test",
"test": "tape test/**/*.js | tap-spec"
},
"repository": {
"type": "git",
"url": "https://github.com/Reactive-Extensions/RxJS.git"
},
"keywords": [
"Rx",
"RxJS",
"Reactive",
"FRP",
"Promise",
"Callback",
"Observable",
"Observer"
],
"author": "Microsoft Corporation",
"license": "MIT",
"bugs": {
"url": "https://github.com/Reactive-Extensions/RxJS/issues"
},
"homepage": "https://github.com/Reactive-Extensions/RxJS",
"devDependencies": {
"babel-core": "^6.4.5",
"babel-loader": "^6.2.1",
"lie": "^3.0.1",
"tap-spec": "^4.1.0",
"tape": "^4.2.2",
"webpack": "^1.12.11"
},
"dependencies": {
"es6-map": "^0.1.3",
"inherits": "^2.0.1"
}
}
================================================
FILE: src/modular/readme.md
================================================
[](https://www.npmjs.com/package/@rxjs/rx)
[](https://www.npmjs.com/package/@rxjs/rx
[](https://gitter.im/Reactive-Extensions/RxJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
**[The Need to go Reactive](#the-need-to-go-reactive)** |
**[About the Reactive Extensions](#about-the-reactive-extensions)** |
**[Batteries Included](#batteries-included)** |
**[Why RxJS?](#why-rxjs)** |
**[Dive In!](#dive-in)** |
**[Resources](#resources)** |
**[Getting Started](#getting-started)** |
**[Contributing](#contributing)** |
**[License](#license)**
# The Reactive Extensions for JavaScript (RxJS) 4.0... #
*...is a set of libraries to compose asynchronous and event-based programs using observable collections and [Array#extras](http://blogs.msdn.com/b/ie/archive/2010/12/13/ecmascript-5-part-2-array-extras.aspx) style composition in JavaScript*
The project is actively developed by [Microsoft](https://microsoft.com/), in collaboration with a community of open source developers.
## The Need to go Reactive ##
Applications, especially on the web have changed over the years from being a simple static page, to DHTML with animations, to the Ajax revolution. Each time, we're adding more complexity, more data, and asynchronous behavior to our applications. How do we manage it all? How do we scale it? By moving towards "Reactive Architectures" which are event-driven, resilient and responsive. With the Reactive Extensions, you have all the tools you need to help build these systems.
## About the Reactive Extensions ##
The Reactive Extensions for JavaScript (RxJS) is a set of libraries for composing asynchronous and event-based programs using observable sequences and fluent query operators that many of you already know by [Array#extras](http://blogs.msdn.com/b/ie/archive/2010/12/13/ecmascript-5-part-2-array-extras.aspx) in JavaScript. Using RxJS, developers represent asynchronous data streams with Observables, query asynchronous data streams using our many operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, RxJS = Observables + Operators + Schedulers.
Whether you are authoring a web-based application in JavaScript or a server-side application in Node.js, you have to deal with asynchronous and event-based programming. Although some patterns are emerging such as the Promise pattern, handling exceptions, cancellation, and synchronization is difficult and error-prone.
Using RxJS, you can represent multiple asynchronous data streams (that come from diverse sources, e.g., stock quote, tweets, computer events, web service requests, etc.), and subscribe to the event stream using the Observer object. The Observable notifies the subscribed Observer instance whenever an event occurs.
Because observable sequences are data streams, you can query them using standard query operators implemented by the Observable type. Thus you can filter, project, aggregate, compose and perform time-based operations on multiple events easily by using these operators. In addition, there are a number of other reactive stream specific operators that allow powerful queries to be written. Cancellation, exceptions, and synchronization are also handled gracefully by using the methods on the Observable object.
But the best news of all is that you already know how to program like this. Take for example the following JavaScript code, where we get some stock data and then manipulate and iterate the results.
```js
/* Get stock data somehow */
const source = getAsyncStockData();
const subscription = source
.filter(quote => quote.price > 30)
.map(quote => quote.price)
.forEach(price => console.log(`Prices higher than $30: ${price}`);
```
Now what if this data were to come as some sort of event, for example a stream, such as a WebSocket? Then we could pretty much write the same query to iterate our data, with very little change.
```js
/* Get stock data somehow */
const source = getAsyncStockData();
const subscription = source
.filter(quote => quote.price > 30)
.map(quote => quote.price)
.subscribe(
price => console.log(`Prices higher than $30: ${price}`),
err => console.log(`Something went wrong: ${err.message}`);
);
/* When we're done */
subscription.dispose();
```
The only difference is that we can handle the errors inline with our subscription. And when we're no longer interested in receiving the data as it comes streaming in, we call `dispose` on our subscription. Note the use of `subscribe` instead of `forEach`. We could also use `forEach` which is an alias for `subscribe` but we highly suggest you use `subscribe`.
## Batteries Included ##
Sure, there are a lot of ways to get started with RxJS. Since RxJS has been built using the CommonJS style of modules, you can either take the whole thing via Node.js with requiring `@rxjs/rx` or simply in your browser using the files of `dist/rx.all.js` or `dist/rx.all.min.js`. We also have smaller versions such as a modular version of `rx.lite` which you can get via Node by requiring `@rxjs/rx/rx.lite` or in your browser `dist/rx.lite.js` or `dist/rx.lite.min.js`.
```js
var Rx = require('@rxjs/rx');
const subscription = Rx.Observable.fromArray([1,2,3])
.filter(x => x % 2 === 0)
.map(x => x + 2)
.subscribe(x => console.log(`The answer is ${x}`));
// => The answer is 4
```
How much you include is up to you. For example, want only a few operators?, then simply require what you need and leave the rest behind.
```js
const fromArray = require('@rx/rx/observable/fromarray');
const filter = require('@rxjs/rx/observable/filter');
const map = require('@rxjs/rx/observable/map');
const source = fromArray([1,2,3]);
const filtered = filter(source, x => x % 2 === 0);
const mapped = map(filtered, x => x + 2);
const subscription = mapped.subscribe( x => console.log(`The answer is ${x}`) );
// => The answer is 4
```
Optionally you can add right to the Observable itself such as:
```js
const Observable = require('@rxjs/rx/observable');
// Add class methods
Observable.addToObject({
fromArray: require('@rxjs/rx/observable/fromarray')
});
// Add instance methods
Observable.addToPrototype({
filter: require('@rxjs/rx/observable/filter'),
map: require('@rxjs/rx/observable/map')
});
const subscription = Observable.fromArray([1,2,3])
.filter(x => x % 2 === 0)
.map(x => x + 2)
.subscribe(x => console.log(`The answer is ${x}`));
```
## Why RxJS? ##
One question you may ask yourself is why RxJS? What about Promises? Promises are good for solving asynchronous operations such as querying a service with an XMLHttpRequest, where the expected behavior is one value and then completion. Reactive Extensions for JavaScript unify both the world of Promises, callbacks as well as evented data such as DOM Input, Web Workers, and Web Sockets. Unifying these concepts enables rich composition.
To give you an idea about rich composition, we can create an autocompletion service which takes user input from a text input and then throttles queries a service (to avoid flooding the service with calls for every key stroke).
First, we'll reference the JavaScript files, including jQuery, although RxJS has no dependencies on jQuery...
```html
```
Next, we'll get the user input from an input, listening to the keyup event by using the `Rx.Observable.fromEvent` method. This will either use the event binding from [jQuery](http://jquery.com), [Zepto](http://zeptojs.com/), [AngularJS](https://angularjs.org/), [Backbone.js](http://backbonejs.org/) and [Ember.js](http://emberjs.com/) if available, and if not, falls back to the native event binding. This gives you consistent ways of thinking of events depending on your framework, so there are no surprises.
```js
const $input = $('#input');
const $results = $('#results');
/* Only get the value from each key up */
var keyups = Rx.Observable.fromEvent($input, 'keyup')
.pluck('target', 'value')
.filter(text => text.length > 2 );
/* Now debounce the input for 500ms */
var debounced = keyups
.debounce(500 /* ms */);
/* Now get only distinct values, so we eliminate the arrows and other control characters */
var distinct = debounced
.distinctUntilChanged();
```
Now, let's query Wikipedia! In RxJS, we can instantly bind to any [Promises A+](https://github.com/promises-aplus/promises-spec) implementation through the `Rx.Observable.fromPromise` method. Or, directly return it and RxJS will wrap it for you.
```js
function searchWikipedia (term) {
return $.ajax({
url: 'https://en.wikipedia.org/w/api.php',
dataType: 'jsonp',
data: {
action: 'opensearch',
format: 'json',
search: term
}
}).promise();
}
```
Once that is created, we can tie together the distinct throttled input and query the service. In this case, we'll call `flatMapLatest` to get the value and ensure we're not introducing any out of order sequence calls.
```js
const suggestions = distinct
.flatMapLatest(searchWikipedia);
```
Finally, we call the `subscribe` method on our observable sequence to start pulling data.
```js
suggestions.subscribe(
data => {
$results
.empty()
.append($.map(data[1], value => $('
";
runLoggingCallbacks( "log", QUnit, details );
config.current.assertions.push({
result: false,
message: output
});
},
url: function( params ) {
params = extend( extend( {}, QUnit.urlParams ), params );
var key,
querystring = "?";
for ( key in params ) {
if ( !hasOwn.call( params, key ) ) {
continue;
}
querystring += encodeURIComponent( key ) + "=" +
encodeURIComponent( params[ key ] ) + "&";
}
return window.location.protocol + "//" + window.location.host +
window.location.pathname + querystring.slice( 0, -1 );
},
extend: extend,
id: id,
addEvent: addEvent
// load, equiv, jsDump, diff: Attached later
});
/**
* @deprecated: Created for backwards compatibility with test runner that set the hook function
* into QUnit.{hook}, instead of invoking it and passing the hook function.
* QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
* Doing this allows us to tell if the following methods have been overwritten on the actual
* QUnit object.
*/
extend( QUnit.constructor.prototype, {
// Logging callbacks; all receive a single argument with the listed properties
// run test/logs.html for any related changes
begin: registerLoggingCallback( "begin" ),
// done: { failed, passed, total, runtime }
done: registerLoggingCallback( "done" ),
// log: { result, actual, expected, message }
log: registerLoggingCallback( "log" ),
// testStart: { name }
testStart: registerLoggingCallback( "testStart" ),
// testDone: { name, failed, passed, total, duration }
testDone: registerLoggingCallback( "testDone" ),
// moduleStart: { name }
moduleStart: registerLoggingCallback( "moduleStart" ),
// moduleDone: { name, failed, passed, total }
moduleDone: registerLoggingCallback( "moduleDone" )
});
if ( typeof document === "undefined" || document.readyState === "complete" ) {
config.autorun = true;
}
QUnit.load = function() {
runLoggingCallbacks( "begin", QUnit, {} );
// Initialize the config, saving the execution queue
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
numModules = 0,
moduleFilterHtml = "",
urlConfigHtml = "",
oldconfig = extend( {}, config );
QUnit.init();
extend(config, oldconfig);
config.blocking = false;
len = config.urlConfig.length;
for ( i = 0; i < len; i++ ) {
val = config.urlConfig[i];
if ( typeof val === "string" ) {
val = {
id: val,
label: val,
tooltip: "[no tooltip available]"
};
}
config[ val.id ] = QUnit.urlParams[ val.id ];
urlConfigHtml += "" + val.label + "";
}
moduleFilterHtml += "Module: ";
// `userAgent` initialized at top of scope
userAgent = id( "qunit-userAgent" );
if ( userAgent ) {
userAgent.innerHTML = navigator.userAgent;
}
// `banner` initialized at top of scope
banner = id( "qunit-header" );
if ( banner ) {
banner.innerHTML = "" + banner.innerHTML + " ";
}
// `toolbar` initialized at top of scope
toolbar = id( "qunit-testrunner-toolbar" );
if ( toolbar ) {
// `filter` initialized at top of scope
filter = document.createElement( "input" );
filter.type = "checkbox";
filter.id = "qunit-filter-pass";
addEvent( filter, "click", function() {
var tmp,
ol = document.getElementById( "qunit-tests" );
if ( filter.checked ) {
ol.className = ol.className + " hidepass";
} else {
tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
ol.className = tmp.replace( / hidepass /, " " );
}
if ( defined.sessionStorage ) {
if (filter.checked) {
sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
} else {
sessionStorage.removeItem( "qunit-filter-passed-tests" );
}
}
});
if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
filter.checked = true;
// `ol` initialized at top of scope
ol = document.getElementById( "qunit-tests" );
ol.className = ol.className + " hidepass";
}
toolbar.appendChild( filter );
// `label` initialized at top of scope
label = document.createElement( "label" );
label.setAttribute( "for", "qunit-filter-pass" );
label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." );
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
urlConfigCheckboxesContainer = document.createElement("span");
urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
// For oldIE support:
// * Add handlers to the individual elements instead of the container
// * Use "click" instead of "change"
// * Fallback from event.target to event.srcElement
addEvents( urlConfigCheckboxes, "click", function( event ) {
var params = {},
target = event.target || event.srcElement;
params[ target.name ] = target.checked ? true : undefined;
window.location = QUnit.url( params );
});
toolbar.appendChild( urlConfigCheckboxesContainer );
if (numModules > 1) {
moduleFilter = document.createElement( 'span' );
moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
moduleFilter.innerHTML = moduleFilterHtml;
addEvent( moduleFilter.lastChild, "change", function() {
var selectBox = moduleFilter.getElementsByTagName("select")[0],
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
});
toolbar.appendChild(moduleFilter);
}
}
// `main` initialized at top of scope
main = id( "qunit-fixture" );
if ( main ) {
config.fixture = main.innerHTML;
}
if ( config.autostart ) {
QUnit.start();
}
};
addEvent( window, "load", QUnit.load );
// `onErrorFnPrev` initialized at top of scope
// Preserve other handlers
onErrorFnPrev = window.onerror;
// Cover uncaught exceptions
// Returning true will surpress the default browser handler,
// returning false will let it run.
window.onerror = function ( error, filePath, linerNr ) {
var ret = false;
if ( onErrorFnPrev ) {
ret = onErrorFnPrev( error, filePath, linerNr );
}
// Treat return value as window.onerror itself does,
// Only do our handling if not surpressed.
if ( ret !== true ) {
if ( QUnit.config.current ) {
if ( QUnit.config.current.ignoreGlobalErrors ) {
return true;
}
QUnit.pushFailure( error, filePath + ":" + linerNr );
} else {
QUnit.test( "global failure", extend( function() {
QUnit.pushFailure( error, filePath + ":" + linerNr );
}, { validTest: validTest } ) );
}
return false;
}
return ret;
};
function done() {
config.autorun = true;
// Log the last module results
if ( config.currentModule ) {
runLoggingCallbacks( "moduleDone", QUnit, {
name: config.currentModule,
failed: config.moduleStats.bad,
passed: config.moduleStats.all - config.moduleStats.bad,
total: config.moduleStats.all
});
}
var i, key,
banner = id( "qunit-banner" ),
tests = id( "qunit-tests" ),
runtime = +new Date() - config.started,
passed = config.stats.all - config.stats.bad,
html = [
"Tests completed in ",
runtime,
" milliseconds. ",
"",
passed,
" assertions of ",
config.stats.all,
" passed, ",
config.stats.bad,
" failed."
].join( "" );
if ( banner ) {
banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
}
if ( tests ) {
id( "qunit-testresult" ).innerHTML = html;
}
if ( config.altertitle && typeof document !== "undefined" && document.title ) {
// show ✖ for good, ✔ for bad suite result in title
// use escape sequences in case file gets loaded with non-utf-8-charset
document.title = [
( config.stats.bad ? "\u2716" : "\u2714" ),
document.title.replace( /^[\u2714\u2716] /i, "" )
].join( " " );
}
// clear own sessionStorage items if all tests passed
if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
// `key` & `i` initialized at top of scope
for ( i = 0; i < sessionStorage.length; i++ ) {
key = sessionStorage.key( i++ );
if ( key.indexOf( "qunit-test-" ) === 0 ) {
sessionStorage.removeItem( key );
}
}
}
// scroll back to top to show results
if ( window.scrollTo ) {
window.scrollTo(0, 0);
}
runLoggingCallbacks( "done", QUnit, {
failed: config.stats.bad,
passed: passed,
total: config.stats.all,
runtime: runtime
});
}
/** @return Boolean: true if this test should be ran */
function validTest( test ) {
var include,
filter = config.filter && config.filter.toLowerCase(),
module = config.module && config.module.toLowerCase(),
fullName = (test.module + ": " + test.testName).toLowerCase();
// Internally-generated tests are always valid
if ( test.callback && test.callback.validTest === validTest ) {
delete test.callback.validTest;
return true;
}
if ( config.testNumber ) {
return test.testNumber === config.testNumber;
}
if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
return false;
}
if ( !filter ) {
return true;
}
include = filter.charAt( 0 ) !== "!";
if ( !include ) {
filter = filter.slice( 1 );
}
// If the filter matches, we need to honour include
if ( fullName.indexOf( filter ) !== -1 ) {
return include;
}
// Otherwise, do the opposite
return !include;
}
// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
// Later Safari and IE10 are supposed to support error.stack as well
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
function extractStacktrace( e, offset ) {
offset = offset === undefined ? 3 : offset;
var stack, include, i;
if ( e.stacktrace ) {
// Opera
return e.stacktrace.split( "\n" )[ offset + 3 ];
} else if ( e.stack ) {
// Firefox, Chrome
stack = e.stack.split( "\n" );
if (/^error$/i.test( stack[0] ) ) {
stack.shift();
}
if ( fileName ) {
include = [];
for ( i = offset; i < stack.length; i++ ) {
if ( stack[ i ].indexOf( fileName ) !== -1 ) {
break;
}
include.push( stack[ i ] );
}
if ( include.length ) {
return include.join( "\n" );
}
}
return stack[ offset ];
} else if ( e.sourceURL ) {
// Safari, PhantomJS
// hopefully one day Safari provides actual stacktraces
// exclude useless self-reference for generated Error objects
if ( /qunit.js$/.test( e.sourceURL ) ) {
return;
}
// for actual exceptions, this is useful
return e.sourceURL + ":" + e.line;
}
}
function sourceFromStacktrace( offset ) {
try {
throw new Error();
} catch ( e ) {
return extractStacktrace( e, offset );
}
}
/**
* Escape text for attribute or text content.
*/
function escapeText( s ) {
if ( !s ) {
return "";
}
s = s + "";
// Both single quotes and double quotes (for attributes)
return s.replace( /['"<>&]/g, function( s ) {
switch( s ) {
case '\'':
return ''';
case '"':
return '"';
case '<':
return '<';
case '>':
return '>';
case '&':
return '&';
}
});
}
function synchronize( callback, last ) {
config.queue.push( callback );
if ( config.autorun && !config.blocking ) {
process( last );
}
}
function process( last ) {
function next() {
process( last );
}
var start = new Date().getTime();
config.depth = config.depth ? config.depth + 1 : 1;
while ( config.queue.length && !config.blocking ) {
if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
config.queue.shift()();
} else {
window.setTimeout( next, 13 );
break;
}
}
config.depth--;
if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
done();
}
}
function saveGlobal() {
config.pollution = [];
if ( config.noglobals ) {
for ( var key in window ) {
// in Opera sometimes DOM element ids show up here, ignore them
if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) {
continue;
}
config.pollution.push( key );
}
}
}
function checkPollution() {
var newGlobals,
deletedGlobals,
old = config.pollution;
saveGlobal();
newGlobals = diff( config.pollution, old );
if ( newGlobals.length > 0 ) {
QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
}
deletedGlobals = diff( old, config.pollution );
if ( deletedGlobals.length > 0 ) {
QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
}
}
// returns a new Array with the elements that are in a but not in b
function diff( a, b ) {
var i, j,
result = a.slice();
for ( i = 0; i < result.length; i++ ) {
for ( j = 0; j < b.length; j++ ) {
if ( result[i] === b[j] ) {
result.splice( i, 1 );
i--;
break;
}
}
}
return result;
}
function extend( a, b ) {
for ( var prop in b ) {
if ( b[ prop ] === undefined ) {
delete a[ prop ];
// Avoid "Member not found" error in IE8 caused by setting window.constructor
} else if ( prop !== "constructor" || a !== window ) {
a[ prop ] = b[ prop ];
}
}
return a;
}
/**
* @param {HTMLElement} elem
* @param {string} type
* @param {Function} fn
*/
function addEvent( elem, type, fn ) {
// Standards-based browsers
if ( elem.addEventListener ) {
elem.addEventListener( type, fn, false );
// IE
} else {
elem.attachEvent( "on" + type, fn );
}
}
/**
* @param {Array|NodeList} elems
* @param {string} type
* @param {Function} fn
*/
function addEvents( elems, type, fn ) {
var i = elems.length;
while ( i-- ) {
addEvent( elems[i], type, fn );
}
}
function hasClass( elem, name ) {
return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
}
function addClass( elem, name ) {
if ( !hasClass( elem, name ) ) {
elem.className += (elem.className ? " " : "") + name;
}
}
function removeClass( elem, name ) {
var set = " " + elem.className + " ";
// Class name may appear multiple times
while ( set.indexOf(" " + name + " ") > -1 ) {
set = set.replace(" " + name + " " , " ");
}
// If possible, trim it for prettiness, but not neccecarily
elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
}
function id( name ) {
return !!( typeof document !== "undefined" && document && document.getElementById ) &&
document.getElementById( name );
}
function registerLoggingCallback( key ) {
return function( callback ) {
config[key].push( callback );
};
}
// Supports deprecated method of completely overwriting logging callbacks
function runLoggingCallbacks( key, scope, args ) {
var i, callbacks;
if ( QUnit.hasOwnProperty( key ) ) {
QUnit[ key ].call(scope, args );
} else {
callbacks = config[ key ];
for ( i = 0; i < callbacks.length; i++ ) {
callbacks[ i ].call( scope, args );
}
}
}
// Test for equality any JavaScript type.
// Author: Philippe Rathé
QUnit.equiv = (function() {
// Call the o related callback with the given arguments.
function bindCallbacks( o, callbacks, args ) {
var prop = QUnit.objectType( o );
if ( prop ) {
if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
return callbacks[ prop ].apply( callbacks, args );
} else {
return callbacks[ prop ]; // or undefined
}
}
}
// the real equiv function
var innerEquiv,
// stack to decide between skip/abort functions
callers = [],
// stack to avoiding loops from circular referencing
parents = [],
getProto = Object.getPrototypeOf || function ( obj ) {
return obj.__proto__;
},
callbacks = (function () {
// for string, boolean, number and null
function useStrictEquality( b, a ) {
/*jshint eqeqeq:false */
if ( b instanceof a.constructor || a instanceof b.constructor ) {
// to catch short annotaion VS 'new' annotation of a
// declaration
// e.g. var i = 1;
// var j = new Number(1);
return a == b;
} else {
return a === b;
}
}
return {
"string": useStrictEquality,
"boolean": useStrictEquality,
"number": useStrictEquality,
"null": useStrictEquality,
"undefined": useStrictEquality,
"nan": function( b ) {
return isNaN( b );
},
"date": function( b, a ) {
return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
},
"regexp": function( b, a ) {
return QUnit.objectType( b ) === "regexp" &&
// the regex itself
a.source === b.source &&
// and its modifers
a.global === b.global &&
// (gmi) ...
a.ignoreCase === b.ignoreCase &&
a.multiline === b.multiline &&
a.sticky === b.sticky;
},
// - skip when the property is a method of an instance (OOP)
// - abort otherwise,
// initial === would have catch identical references anyway
"function": function() {
var caller = callers[callers.length - 1];
return caller !== Object && typeof caller !== "undefined";
},
"array": function( b, a ) {
var i, j, len, loop;
// b could be an object literal here
if ( QUnit.objectType( b ) !== "array" ) {
return false;
}
len = a.length;
if ( len !== b.length ) {
// safe and faster
return false;
}
// track reference to avoid circular references
parents.push( a );
for ( i = 0; i < len; i++ ) {
loop = false;
for ( j = 0; j < parents.length; j++ ) {
if ( parents[j] === a[i] ) {
loop = true;// dont rewalk array
}
}
if ( !loop && !innerEquiv(a[i], b[i]) ) {
parents.pop();
return false;
}
}
parents.pop();
return true;
},
"object": function( b, a ) {
var i, j, loop,
// Default to true
eq = true,
aProperties = [],
bProperties = [];
// comparing constructors is more strict than using
// instanceof
if ( a.constructor !== b.constructor ) {
// Allow objects with no prototype to be equivalent to
// objects with Object as their constructor.
if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
return false;
}
}
// stack constructor before traversing properties
callers.push( a.constructor );
// track reference to avoid circular references
parents.push( a );
for ( i in a ) { // be strict: don't ensures hasOwnProperty
// and go deep
loop = false;
for ( j = 0; j < parents.length; j++ ) {
if ( parents[j] === a[i] ) {
// don't go down the same path twice
loop = true;
}
}
aProperties.push(i); // collect a's properties
if (!loop && !innerEquiv( a[i], b[i] ) ) {
eq = false;
break;
}
}
callers.pop(); // unstack, we are done
parents.pop();
for ( i in b ) {
bProperties.push( i ); // collect b's properties
}
// Ensures identical properties name
return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
}
};
}());
innerEquiv = function() { // can take multiple arguments
var args = [].slice.apply( arguments );
if ( args.length < 2 ) {
return true; // end transition
}
return (function( a, b ) {
if ( a === b ) {
return true; // catch the most you can
} else if ( a === null || b === null || typeof a === "undefined" ||
typeof b === "undefined" ||
QUnit.objectType(a) !== QUnit.objectType(b) ) {
return false; // don't lose time with error prone cases
} else {
return bindCallbacks(a, callbacks, [ b, a ]);
}
// apply transition with (1..n) arguments
}( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) );
};
return innerEquiv;
}());
/**
* jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
* http://flesler.blogspot.com Licensed under BSD
* (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
*
* @projectDescription Advanced and extensible data dumping for Javascript.
* @version 1.0.0
* @author Ariel Flesler
* @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
*/
QUnit.jsDump = (function() {
function quote( str ) {
return '"' + str.toString().replace( /"/g, '\\"' ) + '"';
}
function literal( o ) {
return o + "";
}
function join( pre, arr, post ) {
var s = jsDump.separator(),
base = jsDump.indent(),
inner = jsDump.indent(1);
if ( arr.join ) {
arr = arr.join( "," + s + inner );
}
if ( !arr ) {
return pre + post;
}
return [ pre, inner + arr, base + post ].join(s);
}
function array( arr, stack ) {
var i = arr.length, ret = new Array(i);
this.up();
while ( i-- ) {
ret[i] = this.parse( arr[i] , undefined , stack);
}
this.down();
return join( "[", ret, "]" );
}
var reName = /^function (\w+)/,
jsDump = {
// type is used mostly internally, you can fix a (custom)type in advance
parse: function( obj, type, stack ) {
stack = stack || [ ];
var inStack, res,
parser = this.parsers[ type || this.typeOf(obj) ];
type = typeof parser;
inStack = inArray( obj, stack );
if ( inStack !== -1 ) {
return "recursion(" + (inStack - stack.length) + ")";
}
if ( type === "function" ) {
stack.push( obj );
res = parser.call( this, obj, stack );
stack.pop();
return res;
}
return ( type === "string" ) ? parser : this.parsers.error;
},
typeOf: function( obj ) {
var type;
if ( obj === null ) {
type = "null";
} else if ( typeof obj === "undefined" ) {
type = "undefined";
} else if ( QUnit.is( "regexp", obj) ) {
type = "regexp";
} else if ( QUnit.is( "date", obj) ) {
type = "date";
} else if ( QUnit.is( "function", obj) ) {
type = "function";
} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
type = "window";
} else if ( obj.nodeType === 9 ) {
type = "document";
} else if ( obj.nodeType ) {
type = "node";
} else if (
// native arrays
toString.call( obj ) === "[object Array]" ||
// NodeList objects
( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
) {
type = "array";
} else if ( obj.constructor === Error.prototype.constructor ) {
type = "error";
} else {
type = typeof obj;
}
return type;
},
separator: function() {
return this.multiline ? this.HTML ? " " : "\n" : this.HTML ? " " : " ";
},
// extra can be a number, shortcut for increasing-calling-decreasing
indent: function( extra ) {
if ( !this.multiline ) {
return "";
}
var chr = this.indentChar;
if ( this.HTML ) {
chr = chr.replace( /\t/g, " " ).replace( / /g, " " );
}
return new Array( this._depth_ + (extra||0) ).join(chr);
},
up: function( a ) {
this._depth_ += a || 1;
},
down: function( a ) {
this._depth_ -= a || 1;
},
setParser: function( name, parser ) {
this.parsers[name] = parser;
},
// The next 3 are exposed so you can use them
quote: quote,
literal: literal,
join: join,
//
_depth_: 1,
// This is the list of parsers, to modify them, use jsDump.setParser
parsers: {
window: "[Window]",
document: "[Document]",
error: function(error) {
return "Error(\"" + error.message + "\")";
},
unknown: "[Unknown]",
"null": "null",
"undefined": "undefined",
"function": function( fn ) {
var ret = "function",
// functions never have name in IE
name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
if ( name ) {
ret += " " + name;
}
ret += "( ";
ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
},
array: array,
nodelist: array,
"arguments": array,
object: function( map, stack ) {
var ret = [ ], keys, key, val, i;
QUnit.jsDump.up();
keys = [];
for ( key in map ) {
keys.push( key );
}
keys.sort();
for ( i = 0; i < keys.length; i++ ) {
key = keys[ i ];
val = map[ key ];
ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
}
QUnit.jsDump.down();
return join( "{", ret, "}" );
},
node: function( node ) {
var len, i, val,
open = QUnit.jsDump.HTML ? "<" : "<",
close = QUnit.jsDump.HTML ? ">" : ">",
tag = node.nodeName.toLowerCase(),
ret = open + tag,
attrs = node.attributes;
if ( attrs ) {
for ( i = 0, len = attrs.length; i < len; i++ ) {
val = attrs[i].nodeValue;
// IE6 includes all attributes in .attributes, even ones not explicitly set.
// Those have values like undefined, null, 0, false, "" or "inherit".
if ( val && val !== "inherit" ) {
ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
}
}
}
ret += close;
// Show content of TextNode or CDATASection
if ( node.nodeType === 3 || node.nodeType === 4 ) {
ret += node.nodeValue;
}
return ret + open + "/" + tag + close;
},
// function calls it internally, it's the arguments part of the function
functionArgs: function( fn ) {
var args,
l = fn.length;
if ( !l ) {
return "";
}
args = new Array(l);
while ( l-- ) {
// 97 is 'a'
args[l] = String.fromCharCode(97+l);
}
return " " + args.join( ", " ) + " ";
},
// object calls it internally, the key part of an item in a map
key: quote,
// function calls it internally, it's the content of the function
functionCode: "[code]",
// node calls it internally, it's an html attribute value
attribute: quote,
string: quote,
date: quote,
regexp: literal,
number: literal,
"boolean": literal
},
// if true, entities are escaped ( <, >, \t, space and \n )
HTML: false,
// indentation unit
indentChar: " ",
// if true, items in a collection, are separated by a \n, else just a space.
multiline: true
};
return jsDump;
}());
// from jquery.js
function inArray( elem, array ) {
if ( array.indexOf ) {
return array.indexOf( elem );
}
for ( var i = 0, length = array.length; i < length; i++ ) {
if ( array[ i ] === elem ) {
return i;
}
}
return -1;
}
/*
* Javascript Diff Algorithm
* By John Resig (http://ejohn.org/)
* Modified by Chu Alan "sprite"
*
* Released under the MIT license.
*
* More Info:
* http://ejohn.org/projects/javascript-diff-algorithm/
*
* Usage: QUnit.diff(expected, actual)
*
* QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over"
*/
QUnit.diff = (function() {
/*jshint eqeqeq:false, eqnull:true */
function diff( o, n ) {
var i,
ns = {},
os = {};
for ( i = 0; i < n.length; i++ ) {
if ( !hasOwn.call( ns, n[i] ) ) {
ns[ n[i] ] = {
rows: [],
o: null
};
}
ns[ n[i] ].rows.push( i );
}
for ( i = 0; i < o.length; i++ ) {
if ( !hasOwn.call( os, o[i] ) ) {
os[ o[i] ] = {
rows: [],
n: null
};
}
os[ o[i] ].rows.push( i );
}
for ( i in ns ) {
if ( !hasOwn.call( ns, i ) ) {
continue;
}
if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
n[ ns[i].rows[0] ] = {
text: n[ ns[i].rows[0] ],
row: os[i].rows[0]
};
o[ os[i].rows[0] ] = {
text: o[ os[i].rows[0] ],
row: ns[i].rows[0]
};
}
}
for ( i = 0; i < n.length - 1; i++ ) {
if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
n[ i + 1 ] == o[ n[i].row + 1 ] ) {
n[ i + 1 ] = {
text: n[ i + 1 ],
row: n[i].row + 1
};
o[ n[i].row + 1 ] = {
text: o[ n[i].row + 1 ],
row: i + 1
};
}
}
for ( i = n.length - 1; i > 0; i-- ) {
if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
n[ i - 1 ] == o[ n[i].row - 1 ]) {
n[ i - 1 ] = {
text: n[ i - 1 ],
row: n[i].row - 1
};
o[ n[i].row - 1 ] = {
text: o[ n[i].row - 1 ],
row: i - 1
};
}
}
return {
o: o,
n: n
};
}
return function( o, n ) {
o = o.replace( /\s+$/, "" );
n = n.replace( /\s+$/, "" );
var i, pre,
str = "",
out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
oSpace = o.match(/\s+/g),
nSpace = n.match(/\s+/g);
if ( oSpace == null ) {
oSpace = [ " " ];
}
else {
oSpace.push( " " );
}
if ( nSpace == null ) {
nSpace = [ " " ];
}
else {
nSpace.push( " " );
}
if ( out.n.length === 0 ) {
for ( i = 0; i < out.o.length; i++ ) {
str += "" + out.o[i] + oSpace[i] + "";
}
}
else {
if ( out.n[0].text == null ) {
for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
str += "" + out.o[n] + oSpace[n] + "";
}
}
for ( i = 0; i < out.n.length; i++ ) {
if (out.n[i].text == null) {
str += "" + out.n[i] + nSpace[i] + "";
}
else {
// `pre` initialized at top of scope
pre = "";
for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
pre += "" + out.o[n] + oSpace[n] + "";
}
str += " " + out.n[i].text + nSpace[i] + pre;
}
}
}
return str;
};
}());
// for CommonJS enviroments, export everything
if ( typeof exports !== "undefined" ) {
extend( exports, QUnit );
}
// get at whatever the global object is, like window in browsers
}( (function() {return this;}.call()) ));
================================================
FILE: tests/vendor/rsvp.js
================================================
(function(globals) {
var define, requireModule;
(function() {
var registry = {}, seen = {};
define = function(name, deps, callback) {
registry[name] = { deps: deps, callback: callback };
};
requireModule = function(name) {
if (seen[name]) { return seen[name]; }
seen[name] = {};
var mod = registry[name];
if (!mod) {
throw new Error("Module '" + name + "' not found.");
}
var deps = mod.deps,
callback = mod.callback,
reified = [],
exports;
for (var i=0, l=deps.length; i 2) {
resolve(Array.prototype.slice.call(arguments, 1));
} else {
resolve(value);
}
};
}
function denodeify(nodeFunc) {
return function() {
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
var thisArg = this;
var promise = new Promise(function(nodeResolve, nodeReject) {
resolve = nodeResolve;
reject = nodeReject;
});
all(nodeArgs).then(function(nodeArgs) {
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
try {
nodeFunc.apply(thisArg, nodeArgs);
} catch(e) {
reject(e);
}
});
return promise;
};
}
__exports__.denodeify = denodeify;
});
define("rsvp/promise",
["rsvp/config","rsvp/events","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) {
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
}
if (!(promise instanceof Promise)) {
return new Promise(resolver);
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
};
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
this.on('error', onerror);
try {
resolver(resolvePromise, rejectPromise);
} catch(e) {
rejectPromise(e);
}
};
function onerror(event) {
if (config.onerror) {
config.onerror(event.detail);
}
}
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
try {
value = callback(event.detail);
succeeded = true;
} catch(e) {
failed = true;
error = e;
}
} else {
value = event.detail;
succeeded = true;
}
if (handleThenable(promise, value)) {
return;
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
Promise.prototype = {
constructor: Promise,
isRejected: undefined,
isFulfilled: undefined,
rejectedReason: undefined,
fulfillmentValue: undefined,
then: function(done, fail) {
this.off('error', onerror);
var thenPromise = new this.constructor(function() {});
if (this.isFulfilled) {
config.async(function(promise) {
invokeCallback('resolve', thenPromise, done, { detail: promise.fulfillmentValue });
}, this);
}
if (this.isRejected) {
config.async(function(promise) {
invokeCallback('reject', thenPromise, fail, { detail: promise.rejectedReason });
}, this);
}
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
return thenPromise;
},
fail: function(fail) {
return this.then(null, fail);
}
};
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (!handleThenable(promise, value)) {
fulfill(promise, value);
}
}
function handleThenable(promise, value) {
var then = null,
resolved;
try {
if (promise === value) {
throw new TypeError("A promises callback cannot return that same promise.");
}
if (objectOrFunction(value)) {
then = value.then;
if (isFunction(then)) {
then.call(value, function(val) {
if (resolved) { return true; }
resolved = true;
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
if (resolved) { return true; }
resolved = true;
reject(promise, val);
});
return true;
}
}
} catch (error) {
reject(promise, error);
return true;
}
return false;
}
function fulfill(promise, value) {
config.async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isFulfilled = true;
promise.fulfillmentValue = value;
});
}
function reject(promise, value) {
config.async(function() {
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedReason = value;
});
}
__exports__.Promise = Promise;
});
define("rsvp/reject",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function reject(reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
}
__exports__.reject = reject;
});
define("rsvp/resolve",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function resolve(thenable) {
return new Promise(function(resolve, reject) {
resolve(thenable);
});
}
__exports__.resolve = resolve;
});
define("rsvp/rethrow",
["exports"],
function(__exports__) {
"use strict";
var local = (typeof global === "undefined") ? this : global;
function rethrow(reason) {
local.setTimeout(function() {
throw reason;
});
throw reason;
}
__exports__.rethrow = rethrow;
});
define("rsvp",
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/rethrow","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var Promise = __dependency2__.Promise;
var denodeify = __dependency3__.denodeify;
var all = __dependency4__.all;
var hash = __dependency5__.hash;
var rethrow = __dependency6__.rethrow;
var defer = __dependency7__.defer;
var config = __dependency8__.config;
var resolve = __dependency9__.resolve;
var reject = __dependency10__.reject;
function configure(name, value) {
config[name] = value;
}
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
__exports__.hash = hash;
__exports__.rethrow = rethrow;
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
__exports__.reject = reject;
});
window.RSVP = requireModule("rsvp");
})(window);
================================================
FILE: tests/vendor/transducers-0.4.158-min.js
================================================
// transducers-js 0.4.158
// http://github.com/cognitect-labs/transducers-js
//
// Copyright 2014-2015 Cognitect. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License..
;(function(){var d=this;
function f(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==
b&&"undefined"==typeof a.call)return"object";return b}function g(a,b){var c=a.split("."),e=d;c[0]in e||!e.execScript||e.execScript("var "+c[0]);for(var k;c.length&&(k=c.shift());)c.length||void 0===b?e[k]?e=e[k]:e=e[k]={}:e[k]=b};var h="undefined"!=typeof Array.isArray?function(a){return Array.isArray(a)}:function(a){return"array"==f(a)};function l(a){return function(b){return!a.apply(null,Array.prototype.slice.call(arguments,0))}}function m(a){this.a=a}m.prototype["@@transducer/init"]=function(){throw Error("init not implemented");};m.prototype["@@transducer/result"]=function(a){return a};m.prototype["@@transducer/step"]=function(a,b){return this.a(a,b)};function n(a){return"function"==typeof a?new m(a):a}
function p(a){this["@@transducer/reduced"]=!0;this["@@transducer/value"]=a}function q(a){return new p(a)}function r(a){return a instanceof p||a&&a["@@transducer/reduced"]}function t(a){return r(a)?a:q(a)}function u(a){return a["@@transducer/value"]}function v(a){return r(a)?u(a):a}function w(a){return a}
function x(a){var b=arguments.length;if(2==b){var c=arguments[0],e=arguments[1];return function(a){return c(e.apply(null,Array.prototype.slice.call(arguments,0)))}}if(2 /dev/null
else
# If build failed, travis after-failure will send ./travis.sh revert
echo "Reverting dev branch to what master was"
# Save the current changes to a new branch
echo "Creating a new branch for failed build - incoming-pr-fail-$TRAVIS_BUILD_ID"
git checkout -b incoming-pr-fail-$TRAVIS_BUILD_ID
git push $repo incoming-pr-fail-$TRAVIS_BUILD_ID -q 2> /dev/null
git checkout master
fi
echo "Making incoming-pr same as master"
# Merge or revert is done, so make incoming-pr branch at par with master
# This is done to make it ready for accepting the next pull request
git push $repo --delete incoming-pr -q 2> /dev/null
git branch -D incoming-pr
git branch incoming-pr
git push $repo incoming-pr -q 2> /dev/null
================================================
FILE: ts/core/abstractobserver.ts
================================================
///
///
module Rx {
export module internals {
/**
* Abstract base class for implementations of the Observer class.
* This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.
*/
export interface AbstractObserver extends Rx.IObserver, Rx.IDisposable {
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
onNext(value: T): void;
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
onError(exception: any): void;
/**
* Notifies the observer of the end of the sequence.
*/
onCompleted(): void;
isStopped: boolean;
/**
* Disposes the observer, causing it to transition to the stopped state.
*/
dispose(): void;
fail(e: any): boolean;
// Must be implemented by other observers
next(value: T): void;
error(error: any): void;
completed(): void;
}
interface AbstractObserverStatic {
new (): AbstractObserver;
}
export var AbstractObserver: AbstractObserverStatic
}
}
(function() {
var iObserver: Rx.IObserver;
var abstractObserver: Rx.internals.AbstractObserver;
iObserver = abstractObserver;
});
================================================
FILE: ts/core/anonymousobservable.ts
================================================
///
module Rx {
export interface AnonymousObservable extends Observable { }
}
(function() {
var observable: Rx.Observable;
var anonymousObservable: Rx.AnonymousObservable;
observable = anonymousObservable;
});
================================================
FILE: ts/core/anonymousobserver.ts
================================================
///
module Rx {
/**
* Class to create an Observer instance from delegate-based implementations of the on* methods.
*/
export interface AnonymousObserver extends Observer {
/**
* Notifies the observer of a new element in the sequence.
* @param {Any} value Next element in the sequence.
*/
onNext(value: T): void;
/**
* Notifies the observer that an exception has occurred.
* @param {Any} error The error that has occurred.
*/
onError(exception: any): void;
/**
* Notifies the observer of the end of the sequence.
*/
onCompleted(): void;
}
interface AnonymousObserverStatic {
/**
* Creates an observer from the specified OnNext, OnError, and OnCompleted actions.
* @param {Any} onNext Observer's OnNext action implementation.
* @param {Any} onError Observer's OnError action implementation.
* @param {Any} onCompleted Observer's OnCompleted action implementation.
*/
new (onNext?: (value: T) => void, onError?: (exception: any) => void, onCompleted?: () => void): AnonymousObserver;
}
export var AnonymousObserver : AnonymousObserverStatic;
}
(function() {
var iObserver: Rx.IObserver;
var anonymousObserver: Rx.AnonymousObserver;
iObserver = anonymousObserver;
});
================================================
FILE: ts/core/backpressure/controlled.ts
================================================
///
///
module Rx {
export interface Observable {
/**
* Attaches a controller to the observable sequence with the ability to queue.
* @example
* var source = Rx.Observable.interval(100).controlled();
* source.request(3); // Reads 3 values
* @param {bool} enableQueue truthy value to determine if values should be queued pending the next request
* @param {Scheduler} scheduler determines how the requests will be scheduled
* @returns {Observable} The observable sequence which only propagates values on request.
*/
controlled(enableQueue?: boolean, scheduler?: IScheduler): ControlledObservable;
}
export interface ControlledObservable extends Observable {
request(numberOfItems?: number): IDisposable;
}
}
(function() {
var o: Rx.Observable;
var c = o.controlled();
var d: Rx.IDisposable = c.request();
d = c.request();
d = c.request(5);
});
================================================
FILE: ts/core/backpressure/pausable.ts
================================================
///
module Rx {
export interface Observable {
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausable(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
pausable(pauser?: Observable): PausableObservable;
}
export interface PausableObservable extends Observable {
pause(): void;
resume(): void;
}
}
(function() {
var o: Rx.Observable;
var b: Rx.Observable;
var c = o.pausable();
var c = o.pausable(b);
c.pause();
c.resume();
})
================================================
FILE: ts/core/backpressure/pausablebuffered.ts
================================================
///
module Rx {
export interface Observable {
/**
* Pauses the underlying observable sequence based upon the observable sequence which yields true/false,
* and yields the values that were buffered while paused.
* @example
* var pauser = new Rx.Subject();
* var source = Rx.Observable.interval(100).pausableBuffered(pauser);
* @param {Observable} pauser The observable sequence used to pause the underlying sequence.
* @returns {Observable} The observable sequence which is paused based upon the pauser.
*/
pausableBuffered(pauser?: Observable): PausableObservable;
}
}
(function() {
var o: Rx.Observable;
var b: Rx.Observable;
var c = o.pausableBuffered();
var c = o.pausableBuffered(b);
})
================================================
FILE: ts/core/backpressure/pauser.ts
================================================
module Rx {
/**
* Used to pause and resume streams.
*/
export interface Pauser {
/**
* Pauses the underlying sequence.
*/
pause(): void;
/**
* Resumes the underlying sequence.
*/
resume(): void;
}
}
(function() {
var p: Rx.Pauser;
p.pause;
p.resume;
})
================================================
FILE: ts/core/backpressure/stopandwait.ts
================================================
///
module Rx {
export interface ControlledObservable {
/**
* Attaches a stop and wait observable to the current observable.
* @returns {Observable} A stop and wait observable.
*/
stopAndWait(): Observable;
}
}
(function() {
var observer: Rx.Observable;
var controlledObserver: Rx.ControlledObservable;
observer = controlledObserver.stopAndWait();
})
================================================
FILE: ts/core/backpressure/windowed.ts
================================================
///
module Rx {
export interface ControlledObservable {
/**
* Creates a sliding windowed observable based upon the window size.
* @param {Number} windowSize The number of items in the window
* @returns {Observable} A windowed observable based upon the window size.
*/
windowed(windowSize: number): Observable;
}
}
(function() {
var observer: Rx.Observable;
var controlledObserver: Rx.ControlledObservable;
observer = controlledObserver.windowed(1);
})
================================================
FILE: ts/core/checkedobserver.ts
================================================
///
module Rx {
export interface CheckedObserver extends Observer {
checkAccess(): void;
}
}
(function() {
var iObserver: Rx.IObserver;
var checkedObserver: Rx.CheckedObserver;
iObserver = checkedObserver;
checkedObserver.checkAccess();
});
================================================
FILE: ts/core/concurrency/currentthreadscheduler.ts
================================================
///
module Rx {
export interface ICurrentThreadScheduler extends IScheduler {
scheduleRequired(): boolean;
}
export interface SchedulerStatic {
currentThread: ICurrentThreadScheduler;
}
}
(function() {
var a: Rx.ICurrentThreadScheduler;
a.scheduleRequired();
a = Rx.Scheduler.currentThread;
})
================================================
FILE: ts/core/concurrency/defaultscheduler.ts
================================================
///
module Rx {
export interface SchedulerStatic {
default: IScheduler;
async: IScheduler;
}
}
(function() {
var s : Rx.IScheduler;
s = Rx.Scheduler.async;
s = Rx.Scheduler.default;
})
================================================
FILE: ts/core/concurrency/historicalscheduler.ts
================================================
///
module Rx {
export interface HistoricalScheduler extends VirtualTimeScheduler {
}
export var HistoricalScheduler: {
/**
* Creates a new historical scheduler with the specified initial clock value.
* @constructor
* @param {Number} initialClock Initial value for the clock.
* @param {Function} comparer Comparer to determine causality of events based on absolute time.
*/
new (initialClock: number, comparer: _Comparer): HistoricalScheduler;
};
}
(function() {
var a: Rx.HistoricalScheduler = new Rx.HistoricalScheduler(1, (a, b) => 1);
})
================================================
FILE: ts/core/concurrency/immediatescheduler.ts
================================================
///
module Rx {
export interface SchedulerStatic {
immediate: IScheduler;
}
}
(function() {
var s : Rx.IScheduler;
s = Rx.Scheduler.immediate;
})
================================================
FILE: ts/core/concurrency/scheduleditem.ts
================================================
///
///
module Rx {
export module internals {
export interface ScheduledItem {
scheduler: IScheduler;
state: TTime;
action: (scheduler: IScheduler, state: any) => IDisposable;
dueTime: TTime;
comparer: (x: TTime, y: TTime) => number;
disposable: SingleAssignmentDisposable;
invoke(): void;
compareTo(other: ScheduledItem): number;
isCancelled(): boolean;
invokeCore(): IDisposable;
}
interface ScheduledItemStatic {
new (scheduler: IScheduler, state: any, action: (scheduler: IScheduler, state: any) => IDisposable, dueTime: TTime, comparer?: _Comparer):ScheduledItem;
}
export var ScheduledItem: ScheduledItemStatic
}
}
(function() {
var item = new Rx.internals.ScheduledItem(Rx.Scheduler.default, {}, (sc, s) => Rx.Disposable.create(() => {}), 100);
var item = new Rx.internals.ScheduledItem(Rx.Scheduler.default, {}, (sc, s) => Rx.Disposable.create(() => {}), 100, (x, y) => 500);
item.scheduler
item.state;
item.action;
item.dueTime;
item.comparer;
item.disposable;
item.invoke();
var n: number = item.compareTo(item);
var b: boolean = item.isCancelled();
var d : Rx.IDisposable= item.invokeCore();
})
================================================
FILE: ts/core/concurrency/scheduleperiodicrecursive.ts
================================================
///
module Rx {
export module internals {
export interface SchedulePeriodicRecursive {
start(): IDisposable;
}
interface SchedulePeriodicRecursiveStatic {
new (scheduler: any, state: any, period: any, action: any) : SchedulePeriodicRecursive;
}
export var SchedulePeriodicRecursive: SchedulePeriodicRecursiveStatic;
}
}
(function() {
var item = new Rx.internals.SchedulePeriodicRecursive(undefined, undefined, undefined, undefined);
var d : Rx.IDisposable = item.start();
})
================================================
FILE: ts/core/concurrency/scheduler.periodic.ts
================================================
///
module Rx {
export interface IScheduler {
/**
* Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation.
* @param {Mixed} state Initial state passed to the action upon the first iteration.
* @param {Number} period Period for running the work periodically.
* @param {Function} action Action to be executed, potentially updating the state.
* @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort).
*/
schedulePeriodic(state: TState, period: number, action: (state: TState) => TState): IDisposable;
}
}
(function() {
var s : Rx.IScheduler;
var d : Rx.IDisposable = s.schedulePeriodic('state', 100, (s) => s);
})
================================================
FILE: ts/core/concurrency/scheduler.recursive.ts
================================================
///
module Rx {
export interface IScheduler {
/**
* Schedules an action to be executed recursively.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
scheduleRecursive(state: TState, action: (state: TState, action: (state: TState) => void) => void): IDisposable;
/**
* Schedules an action to be executed recursively after a specified relative due time.
* @param {Mixed} state State passed to the action to be executed.
* @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state.
* @param {Number}dueTime Relative time after which to execute the action for the first time.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
scheduleRecursiveFuture(state: TState, dueTime: TTime, action: (state: TState, action: (state: TState, dueTime: TTime) => void) => void): IDisposable;
}
}
(function() {
var s: Rx.IScheduler;
var d: Rx.IDisposable = s.scheduleRecursive('state', (s, a) => Rx.Disposable.empty);
var d: Rx.IDisposable = s.scheduleRecursiveFuture('state', 100, (s, a) => Rx.Disposable.empty);
})
================================================
FILE: ts/core/concurrency/scheduler.ts
================================================
///
module Rx {
export interface IScheduler {
/** Gets the current time according to the local machine's system clock. */
now(): number;
/**
* Schedules an action to be executed.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
schedule(state: TState, action: (scheduler: IScheduler, state: TState) => IDisposable): IDisposable;
/**
* Schedules an action to be executed after dueTime.
* @param state State passed to the action to be executed.
* @param {Function} action Action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
scheduleFuture(state: TState, dueTime: number | Date, action: (scheduler: IScheduler, state: TState) => IDisposable): IDisposable;
}
export interface SchedulerStatic {
/** Gets the current time according to the local machine's system clock. */
now(): number;
/**
* Normalizes the specified TimeSpan value to a positive value.
* @param {Number} timeSpan The time span value to normalize.
* @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0
*/
normalize(timeSpan: number): number;
/** Determines whether the given object is a scheduler */
isScheduler(s: any): boolean;
}
/** Provides a set of static properties to access commonly used schedulers. */
export var Scheduler: SchedulerStatic;
}
(function() {
var s: Rx.IScheduler;
var d: Rx.IDisposable = s.schedule('state', (sh, s ) => Rx.Disposable.empty);
var d: Rx.IDisposable = s.scheduleFuture('state', 100, (sh, s ) => Rx.Disposable.empty);
var n : () => number = Rx.Scheduler.now;
var a : number = Rx.Scheduler.normalize(1000);
})
================================================
FILE: ts/core/concurrency/scheduler.wrappers.ts
================================================
///
module Rx {
export interface IScheduler {
/**
* Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions.
* @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false.
* @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling.
*/
catch(handler: Function): IScheduler;
}
}
(function() {
var s : Rx.IScheduler = Rx.Scheduler.default.catch(() => {});
})
================================================
FILE: ts/core/concurrency/virtualtimescheduler.ts
================================================
///
///
///
module Rx {
export interface VirtualTimeScheduler extends IScheduler {
/**
* Adds a relative time value to an absolute time value.
* @param {Number} absolute Absolute virtual time value.
* @param {Number} relative Relative virtual time value to add.
* @return {Number} Resulting absolute virtual time sum value.
*/
add(from: TAbsolute, by: TRelative): TAbsolute;
/**
* Converts an absolute time to a number
* @param {Any} The absolute time.
* @returns {Number} The absolute time in ms
*/
toAbsoluteTime(duetime: TAbsolute): number;
/**
* Converts the TimeSpan value to a relative virtual time value.
* @param {Number} timeSpan TimeSpan value to convert.
* @return {Number} Corresponding relative virtual time value.
*/
toRelativeTime(duetime: number): TRelative;
/**
* Starts the virtual time scheduler.
*/
start(): IDisposable;
/**
* Stops the virtual time scheduler.
*/
stop(): void;
/**
* Advances the scheduler's clock to the specified time, running all work till that point.
* @param {Number} time Absolute time to advance the scheduler's clock to.
*/
advanceTo(time: TAbsolute): void;
/**
* Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
advanceBy(time: TRelative): void;
/**
* Advances the scheduler's clock by the specified relative time.
* @param {Number} time Relative time to advance the scheduler's clock by.
*/
sleep(time: TRelative): void;
isEnabled: boolean;
/**
* Gets the next scheduled item to be executed.
* @returns {ScheduledItem} The next scheduled item.
*/
getNext(): internals.ScheduledItem;
/**
* Schedules an action to be executed after dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Relative time after which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
scheduleRelative(state: any, dueTime: TRelative, action: (scheduler: IScheduler, state: any) => IDisposable):IDisposable;
/**
* Schedules an action to be executed at dueTime.
* @param {Mixed} state State passed to the action to be executed.
* @param {Number} dueTime Absolute time at which to execute the action.
* @param {Function} action Action to be executed.
* @returns {Disposable} The disposable object used to cancel the scheduled action (best effort).
*/
scheduleAbsolute(state: any, dueTime: TAbsolute, action: (scheduler: IScheduler, state: any) => IDisposable):IDisposable;
}
}
(function() {
interface TA { }
interface TR { }
var vts: Rx.VirtualTimeScheduler;
var b: boolean = vts.isEnabled;
var a: TA = vts.add(100, 500);
var n: number = vts.toAbsoluteTime(1000);
var r: TR = vts.toRelativeTime(1000);
var d: Rx.IDisposable = vts.start();
vts.stop();
vts.advanceTo(null);
vts.advanceBy(
null);
vts.sleep(
null);
var i: Rx.internals.ScheduledItem = vts.getNext();
b = vts.isEnabled;
})
================================================
FILE: ts/core/disposables/booleandisposable.ts
================================================
///
module Rx {
export interface SingleAssignmentDisposable {
/** Performs the task of cleaning up resources. */
dispose(): void;
/** Is this value disposed. */
isDisposed: boolean;
getDisposable(): IDisposable;
setDisposable(value: IDisposable): void;
}
interface SingleAssignmentDisposableStatic {
new() : SingleAssignmentDisposable;
}
export var SingleAssignmentDisposable : SingleAssignmentDisposableStatic;
export interface SerialDisposable {
/** Performs the task of cleaning up resources. */
dispose(): void;
/** Is this value disposed. */
isDisposed: boolean;
getDisposable(): IDisposable;
setDisposable(value: IDisposable): void;
}
interface SerialDisposableStatic {
new() : SerialDisposable;
}
export var SerialDisposable : SerialDisposableStatic;
}
(function() {
var sad: Rx.SingleAssignmentDisposable = new Rx.SingleAssignmentDisposable();
sad.dispose();
sad.isDisposed;
var d = sad.getDisposable();
sad.setDisposable(d);
var sad: Rx.SerialDisposable = new Rx.SerialDisposable();
sad.dispose();
sad.isDisposed;
var d = sad.getDisposable();
sad.setDisposable(d);
});
================================================
FILE: ts/core/disposables/compositedisposable.ts
================================================
///
module Rx {
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
export interface CompositeDisposable extends Disposable {
/**
* Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
* @param {Mixed} item Disposable to add.
*/
add(item: IDisposable): void;
/**
* Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
* @param {Mixed} item Disposable to remove.
* @returns {Boolean} true if found; false otherwise.
*/
remove(item: IDisposable): void;
}
interface CompositeDisposableStatic {
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
new (...disposables: Rx.IDisposable[]): CompositeDisposable;
/**
* Represents a group of disposable resources that are disposed together.
* @constructor
*/
new(disposables: Rx.IDisposable[]): CompositeDisposable;
}
export var CompositeDisposable: CompositeDisposableStatic;
}
(function() {
var cd = new Rx.CompositeDisposable();
var cd = new Rx.CompositeDisposable(Rx.Disposable.create(() => { }));
var cd = new Rx.CompositeDisposable([Rx.Disposable.create(() => { })]);
cd.add(Rx.Disposable.create(() => { }));
cd.remove(Rx.Disposable.create(() => { }));
cd.dispose();
cd.isDisposed;
})
================================================
FILE: ts/core/disposables/disposable.ts
================================================
module Rx {
export interface IDisposable {
dispose(): void;
}
export interface Disposable extends IDisposable {
/** Is this value disposed. */
isDisposed?: boolean;
}
interface DisposableStatic {
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
new (action: () => void): Disposable;
/**
* Creates a disposable object that invokes the specified action when disposed.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
* @return {Disposable} The disposable object that runs the given action upon disposal.
*/
create(action: () => void): Disposable;
/**
* Gets the disposable that does nothing when disposed.
*/
empty: IDisposable;
/**
* Validates whether the given object is a disposable
* @param {Object} Object to test whether it has a dispose method
* @returns {Boolean} true if a disposable object, else false.
*/
isDisposable(d: any): boolean;
}
/**
* Provides a set of static methods for creating Disposables.
* @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once.
*/
export var Disposable: DisposableStatic;
}
(function() {
var id: Rx.IDisposable;
var d : Rx.Disposable;
id.dispose();
d.dispose();
d.isDisposed;
Rx.Disposable.create(() => {})
Rx.Disposable.empty;
Rx.Disposable.isDisposable(d);
})
================================================
FILE: ts/core/disposables/refcountdisposable.ts
================================================
///
module Rx {
/**
* Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
*/
export interface RefCountDisposable extends Disposable {
/** Performs the task of cleaning up resources. */
dispose(): void;
/** Is this value disposed. */
isDisposed: boolean;
/**
* Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
* @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
*/
getDisposable(): IDisposable;
}
interface RefCountDisposableStatic {
/**
* Initializes a new instance of the RefCountDisposable with the specified disposable.
* @constructor
* @param {Disposable} disposable Underlying disposable.
*/
new(disposable: IDisposable): RefCountDisposable;
}
export var RefCountDisposable : RefCountDisposableStatic;
}
(function() {
var d = Rx.Disposable.create(() => {});
var rcd = new Rx.RefCountDisposable(d);
d = rcd.getDisposable();
rcd.dispose();
rcd.isDisposed;
})
================================================
FILE: ts/core/es5.ts
================================================
module Rx {
// Type alias for observables and promises
export type ObservableOrPromise = IObservable | Observable | Promise;
export type ArrayLike = Array